// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * CCS static data binary parser library
 *
 * Copyright 2019--2020 Intel Corporation
 */

#include <linux/device.h>
#include <linux/errno.h>
#include <linux/limits.h>
#include <linux/mm.h>
#include <linux/slab.h>

#include "ccs-data-defs.h"

struct bin_container {
	void *base;
	void *now;
	void *end;
	size_t size;
};

static void *bin_alloc(struct bin_container *bin, size_t len)
{
	void *ptr;

	len = ALIGN(len, 8);

	if (bin->end - bin->now < len)
		return NULL;

	ptr = bin->now;
	bin->now += len;

	return ptr;
}

static void bin_reserve(struct bin_container *bin, size_t len)
{
	bin->size += ALIGN(len, 8);
}

static int bin_backing_alloc(struct bin_container *bin)
{
	bin->base = bin->now = kvzalloc(bin->size, GFP_KERNEL);
	if (!bin->base)
		return -ENOMEM;

	bin->end = bin->base + bin->size;

	return 0;
}

#define is_contained(var, endp)				\
	(sizeof(*var) <= (endp) - (void *)(var))
#define has_headroom(ptr, headroom, endp)	\
	((headroom) <= (endp) - (void *)(ptr))
#define is_contained_with_headroom(var, headroom, endp)		\
	(sizeof(*var) + (headroom) <= (endp) - (void *)(var))

static int
ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier *__len,
				size_t *__hlen, size_t *__plen,
				const void *endp)
{
	size_t hlen, plen;

	if (!is_contained(__len, endp))
		return -ENODATA;

	switch (__len->length >> CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) {
	case CCS_DATA_LENGTH_SPECIFIER_1:
		hlen = sizeof(*__len);
		plen = __len->length &
			((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1);
		break;
	case CCS_DATA_LENGTH_SPECIFIER_2: {
		struct __ccs_data_length_specifier2 *__len2 = (void *)__len;

		if (!is_contained(__len2, endp))
			return -ENODATA;

		hlen = sizeof(*__len2);
		plen = ((size_t)
			(__len2->length[0] &
			 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1))
			<< 8) + __len2->length[1];
		break;
	}
	case CCS_DATA_LENGTH_SPECIFIER_3: {
		struct __ccs_data_length_specifier3 *__len3 = (void *)__len;

		if (!is_contained(__len3, endp))
			return -ENODATA;

		hlen = sizeof(*__len3);
		plen = ((size_t)
			(__len3->length[0] &
			 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1))
			<< 16) + (__len3->length[0] << 8) + __len3->length[1];
		break;
	}
	default:
		return -EINVAL;
	}

	if (!has_headroom(__len, hlen + plen, endp))
		return -ENODATA;

	*__hlen = hlen;
	*__plen = plen;

	return 0;
}

static u8
ccs_data_parse_format_version(const struct __ccs_data_block *block)
{
	return block->id >> CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT;
}

static u8 ccs_data_parse_block_id(const struct __ccs_data_block *block,
				       bool is_first)
{
	if (!is_first)
		return block->id;

	return block->id & ((1 << CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT) - 1);
}

static int ccs_data_parse_version(struct bin_container *bin,
				  struct ccs_data_container *ccsdata,
				  const void *payload, const void *endp)
{
	const struct __ccs_data_block_version *v = payload;
	struct ccs_data_block_version *vv;

	if (v + 1 != endp)
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(*ccsdata->version));
		return 0;
	}

	ccsdata->version = bin_alloc(bin, sizeof(*ccsdata->version));
	if (!ccsdata->version)
		return -ENOMEM;

	vv = ccsdata->version;
	vv->version_major = ((u16)v->static_data_version_major[0] << 8) +
		v->static_data_version_major[1];
	vv->version_minor = ((u16)v->static_data_version_minor[0] << 8) +
		v->static_data_version_minor[1];
	vv->date_year =  ((u16)v->year[0] << 8) + v->year[1];
	vv->date_month = v->month;
	vv->date_day = v->day;

	return 0;
}

static void print_ccs_data_version(struct device *dev,
				   struct ccs_data_block_version *v)
{
	dev_dbg(dev,
		"static data version %4.4x.%4.4x, date %4.4u-%2.2u-%2.2u\n",
		v->version_major, v->version_minor,
		v->date_year, v->date_month, v->date_day);
}

static int ccs_data_block_parse_header(const struct __ccs_data_block *block,
				       bool is_first, unsigned int *__block_id,
				       const void **payload,
				       const struct __ccs_data_block **next_block,
				       const void *endp, struct device *dev,
				       bool verbose)
{
	size_t plen, hlen;
	u8 block_id;
	int rval;

	if (!is_contained(block, endp))
		return -ENODATA;

	rval = ccs_data_parse_length_specifier(&block->length, &hlen, &plen,
					       endp);
	if (rval < 0)
		return rval;

	block_id = ccs_data_parse_block_id(block, is_first);

	if (verbose)
		dev_dbg(dev,
			"Block ID 0x%2.2x, header length %zu, payload length %zu\n",
			block_id, hlen, plen);

	if (!has_headroom(&block->length, hlen + plen, endp))
		return -ENODATA;

	if (__block_id)
		*__block_id = block_id;

	if (payload)
		*payload = (void *)&block->length + hlen;

	if (next_block)
		*next_block = (void *)&block->length + hlen + plen;

	return 0;
}

static int ccs_data_parse_regs(struct bin_container *bin,
			       struct ccs_reg **__regs,
			       size_t *__num_regs, const void *payload,
			       const void *endp, struct device *dev)
{
	struct ccs_reg *regs_base = NULL, *regs = NULL;
	size_t num_regs = 0;
	u16 addr = 0;

	if (bin->base && __regs) {
		regs = regs_base = bin_alloc(bin, sizeof(*regs) * *__num_regs);
		if (!regs)
			return -ENOMEM;
	}

	while (payload < endp && num_regs < INT_MAX) {
		const struct __ccs_data_block_regs *r = payload;
		size_t len;
		const void *data;

		if (!is_contained(r, endp))
			return -ENODATA;

		switch (r->reg_len >> CCS_DATA_BLOCK_REGS_SEL_SHIFT) {
		case CCS_DATA_BLOCK_REGS_SEL_REGS:
			addr += r->reg_len & CCS_DATA_BLOCK_REGS_ADDR_MASK;
			len = ((r->reg_len & CCS_DATA_BLOCK_REGS_LEN_MASK)
			       >> CCS_DATA_BLOCK_REGS_LEN_SHIFT) + 1;

			if (!is_contained_with_headroom(r, len, endp))
				return -ENODATA;

			data = r + 1;
			break;
		case CCS_DATA_BLOCK_REGS_SEL_REGS2: {
			const struct __ccs_data_block_regs2 *r2 = payload;

			if (!is_contained(r2, endp))
				return -ENODATA;

			addr += ((u16)(r2->reg_len &
				       CCS_DATA_BLOCK_REGS_2_ADDR_MASK) << 8)
				+ r2->addr;
			len = ((r2->reg_len & CCS_DATA_BLOCK_REGS_2_LEN_MASK)
			       >> CCS_DATA_BLOCK_REGS_2_LEN_SHIFT) + 1;

			if (!is_contained_with_headroom(r2, len, endp))
				return -ENODATA;

			data = r2 + 1;
			break;
		}
		case CCS_DATA_BLOCK_REGS_SEL_REGS3: {
			const struct __ccs_data_block_regs3 *r3 = payload;

			if (!is_contained(r3, endp))
				return -ENODATA;

			addr = ((u16)r3->addr[0] << 8) + r3->addr[1];
			len = (r3->reg_len & CCS_DATA_BLOCK_REGS_3_LEN_MASK) + 1;

			if (!is_contained_with_headroom(r3, len, endp))
				return -ENODATA;

			data = r3 + 1;
			break;
		}
		default:
			return -EINVAL;
		}

		num_regs++;

		if (!bin->base) {
			bin_reserve(bin, len);
		} else if (__regs) {
			if (!regs)
				return -EIO;

			regs->addr = addr;
			regs->len = len;
			regs->value = bin_alloc(bin, len);
			if (!regs->value)
				return -ENOMEM;

			memcpy(regs->value, data, len);
			regs++;
		}

		addr += len;
		payload = data + len;
	}

	if (!bin->base)
		bin_reserve(bin, sizeof(*regs) * num_regs);

	if (__num_regs)
		*__num_regs = num_regs;

	if (bin->base && __regs) {
		if (!regs_base)
			return -EIO;

		*__regs = regs_base;
	}

	return 0;
}

static int ccs_data_parse_reg_rules(struct bin_container *bin,
				    struct ccs_reg **__regs,
				    size_t *__num_regs,
				    const void *payload,
				    const void *endp, struct device *dev)
{
	int rval;

	if (!bin->base)
		return ccs_data_parse_regs(bin, NULL, NULL, payload, endp, dev);

	rval = ccs_data_parse_regs(bin, NULL, __num_regs, payload, endp, dev);
	if (rval)
		return rval;

	return ccs_data_parse_regs(bin, __regs, __num_regs, payload, endp,
				   dev);
}

static void assign_ffd_entry(struct ccs_frame_format_desc *desc,
			     const struct __ccs_data_block_ffd_entry *ent)
{
	desc->pixelcode = ent->pixelcode;
	desc->value = ((u16)ent->value[0] << 8) + ent->value[1];
}

static int ccs_data_parse_ffd(struct bin_container *bin,
			      struct ccs_frame_format_descs **ffd,
			      const void *payload,
			      const void *endp, struct device *dev)
{
	const struct __ccs_data_block_ffd *__ffd = payload;
	const struct __ccs_data_block_ffd_entry *__entry;
	unsigned int i;

	if (!is_contained(__ffd, endp))
		return -ENODATA;

	if ((void *)__ffd + sizeof(*__ffd) +
	    ((u32)__ffd->num_column_descs +
	     (u32)__ffd->num_row_descs) *
	    sizeof(struct __ccs_data_block_ffd_entry) != endp)
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(**ffd));
		bin_reserve(bin, __ffd->num_column_descs *
			    sizeof(struct ccs_frame_format_desc));
		bin_reserve(bin, __ffd->num_row_descs *
			    sizeof(struct ccs_frame_format_desc));

		return 0;
	}

	*ffd = bin_alloc(bin, sizeof(**ffd));
	if (!*ffd)
		return -ENOMEM;

	(*ffd)->num_column_descs = __ffd->num_column_descs;
	(*ffd)->num_row_descs = __ffd->num_row_descs;
	__entry = (void *)(__ffd + 1);

	(*ffd)->column_descs = bin_alloc(bin, __ffd->num_column_descs *
					 sizeof(*(*ffd)->column_descs));
	if (!(*ffd)->column_descs)
		return -ENOMEM;

	for (i = 0; i < __ffd->num_column_descs; i++, __entry++)
		assign_ffd_entry(&(*ffd)->column_descs[i], __entry);

	(*ffd)->row_descs = bin_alloc(bin, __ffd->num_row_descs *
				      sizeof(*(*ffd)->row_descs));
	if (!(*ffd)->row_descs)
		return -ENOMEM;

	for (i = 0; i < __ffd->num_row_descs; i++, __entry++)
		assign_ffd_entry(&(*ffd)->row_descs[i], __entry);

	if (__entry != endp)
		return -EPROTO;

	return 0;
}

static int ccs_data_parse_pdaf_readout(struct bin_container *bin,
				       struct ccs_pdaf_readout **pdaf_readout,
				       const void *payload,
				       const void *endp, struct device *dev)
{
	const struct __ccs_data_block_pdaf_readout *__pdaf = payload;

	if (!is_contained(__pdaf, endp))
		return -ENODATA;

	if (!bin->base) {
		bin_reserve(bin, sizeof(**pdaf_readout));
	} else {
		*pdaf_readout = bin_alloc(bin, sizeof(**pdaf_readout));
		if (!*pdaf_readout)
			return -ENOMEM;

		(*pdaf_readout)->pdaf_readout_info_order =
			__pdaf->pdaf_readout_info_order;
	}

	return ccs_data_parse_ffd(bin, !bin->base ? NULL : &(*pdaf_readout)->ffd,
				  __pdaf + 1, endp, dev);
}

static int ccs_data_parse_rules(struct bin_container *bin,
				struct ccs_rule **__rules,
				size_t *__num_rules, const void *payload,
				const void *endp, struct device *dev)
{
	struct ccs_rule *rules_base = NULL, *rules = NULL, *next_rule = NULL;
	size_t num_rules = 0;
	const void *__next_rule = payload;
	int rval;

	if (bin->base) {
		rules_base = next_rule =
			bin_alloc(bin, sizeof(*rules) * *__num_rules);
		if (!rules_base)
			return -ENOMEM;
	}

	while (__next_rule < endp) {
		size_t rule_hlen, rule_plen, rule_plen2;
		const u8 *__rule_type;
		const void *rule_payload;

		/* Size of a single rule */
		rval = ccs_data_parse_length_specifier(__next_rule, &rule_hlen,
						       &rule_plen, endp);

		if (rval < 0)
			return rval;

		__rule_type = __next_rule + rule_hlen;

		if (!is_contained(__rule_type, endp))
			return -ENODATA;

		rule_payload = __rule_type + 1;
		rule_plen2 = rule_plen - sizeof(*__rule_type);

		if (*__rule_type == CCS_DATA_BLOCK_RULE_ID_IF) {
			const struct __ccs_data_block_rule_if *__if_rules =
				rule_payload;
			const size_t __num_if_rules =
				rule_plen2 / sizeof(*__if_rules);
			struct ccs_if_rule *if_rule;

			if (!has_headroom(__if_rules,
					  sizeof(*__if_rules) * __num_if_rules,
					  rule_payload + rule_plen2))
				return -ENODATA;

			/* Also check there is no extra data */
			if (__if_rules + __num_if_rules !=
			    rule_payload + rule_plen2)
				return -EINVAL;

			if (!bin->base) {
				bin_reserve(bin,
					    sizeof(*if_rule) *
					    __num_if_rules);
				num_rules++;
			} else {
				unsigned int i;

				if (!next_rule)
					return -EIO;

				rules = next_rule;
				next_rule++;

				if_rule = bin_alloc(bin,
						    sizeof(*if_rule) *
						    __num_if_rules);
				if (!if_rule)
					return -ENOMEM;

				for (i = 0; i < __num_if_rules; i++) {
					if_rule[i].addr =
						((u16)__if_rules[i].addr[0]
						 << 8) +
						__if_rules[i].addr[1];
					if_rule[i].value = __if_rules[i].value;
					if_rule[i].mask = __if_rules[i].mask;
				}

				rules->if_rules = if_rule;
				rules->num_if_rules = __num_if_rules;
			}
		} else {
			/* Check there was an if rule before any other rules */
			if (bin->base && !rules)
				return -EINVAL;

			switch (*__rule_type) {
			case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS:
				rval = ccs_data_parse_reg_rules(bin,
								rules ?
								&rules->read_only_regs : NULL,
								rules ?
								&rules->num_read_only_regs : NULL,
								rule_payload,
								rule_payload + rule_plen2,
								dev);
				if (rval)
					return rval;
				break;
			case CCS_DATA_BLOCK_RULE_ID_FFD:
				rval = ccs_data_parse_ffd(bin, rules ?
							  &rules->frame_format : NULL,
							  rule_payload,
							  rule_payload + rule_plen2,
							  dev);
				if (rval)
					return rval;
				break;
			case CCS_DATA_BLOCK_RULE_ID_MSR:
				rval = ccs_data_parse_reg_rules(bin,
								rules ?
								&rules->manufacturer_regs : NULL,
								rules ?
								&rules->num_manufacturer_regs : NULL,
								rule_payload,
								rule_payload + rule_plen2,
								dev);
				if (rval)
					return rval;
				break;
			case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT:
				rval = ccs_data_parse_pdaf_readout(bin,
								   rules ?
								   &rules->pdaf_readout : NULL,
								   rule_payload,
								   rule_payload + rule_plen2,
								   dev);
				if (rval)
					return rval;
				break;
			default:
				dev_dbg(dev,
					"Don't know how to handle rule type %u!\n",
					*__rule_type);
				return -EINVAL;
			}
		}
		__next_rule = __next_rule + rule_hlen + rule_plen;
	}

	if (!bin->base) {
		bin_reserve(bin, sizeof(*rules) * num_rules);
		*__num_rules = num_rules;
	} else {
		if (!rules_base)
			return -EIO;

		*__rules = rules_base;
	}

	return 0;
}

static int ccs_data_parse_pdaf(struct bin_container *bin, struct ccs_pdaf_pix_loc **pdaf,
			       const void *payload, const void *endp,
			       struct device *dev)
{
	const struct __ccs_data_block_pdaf_pix_loc *__pdaf = payload;
	const struct __ccs_data_block_pdaf_pix_loc_block_desc_group *__bdesc_group;
	const struct __ccs_data_block_pdaf_pix_loc_pixel_desc *__pixel_desc;
	unsigned int i;
	u16 num_block_desc_groups;
	u8 max_block_type_id = 0;
	const u8 *__num_pixel_descs;

	if (!is_contained(__pdaf, endp))
		return -ENODATA;

	if (bin->base) {
		*pdaf = bin_alloc(bin, sizeof(**pdaf));
		if (!*pdaf)
			return -ENOMEM;
	} else {
		bin_reserve(bin, sizeof(**pdaf));
	}

	num_block_desc_groups =
		((u16)__pdaf->num_block_desc_groups[0] << 8) +
		__pdaf->num_block_desc_groups[1];

	if (bin->base) {
		(*pdaf)->main_offset_x =
			((u16)__pdaf->main_offset_x[0] << 8) +
			__pdaf->main_offset_x[1];
		(*pdaf)->main_offset_y =
			((u16)__pdaf->main_offset_y[0] << 8) +
			__pdaf->main_offset_y[1];
		(*pdaf)->global_pdaf_type = __pdaf->global_pdaf_type;
		(*pdaf)->block_width = __pdaf->block_width;
		(*pdaf)->block_height = __pdaf->block_height;
		(*pdaf)->num_block_desc_groups = num_block_desc_groups;
	}

	__bdesc_group = (const void *)(__pdaf + 1);

	if (bin->base) {
		(*pdaf)->block_desc_groups =
			bin_alloc(bin,
				  sizeof(struct ccs_pdaf_pix_loc_block_desc_group) *
				  num_block_desc_groups);
		if (!(*pdaf)->block_desc_groups)
			return -ENOMEM;
	} else {
		bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc_group) *
			    num_block_desc_groups);
	}

	for (i = 0; i < num_block_desc_groups; i++) {
		const struct __ccs_data_block_pdaf_pix_loc_block_desc *__bdesc;
		u16 num_block_descs;
		unsigned int j;

		if (!is_contained(__bdesc_group, endp))
			return -ENODATA;

		num_block_descs =
			((u16)__bdesc_group->num_block_descs[0] << 8) +
			__bdesc_group->num_block_descs[1];

		if (bin->base) {
			(*pdaf)->block_desc_groups[i].repeat_y =
				__bdesc_group->repeat_y;
			(*pdaf)->block_desc_groups[i].num_block_descs =
				num_block_descs;
		}

		__bdesc = (const void *)(__bdesc_group + 1);

		if (bin->base) {
			(*pdaf)->block_desc_groups[i].block_descs =
				bin_alloc(bin,
					  sizeof(struct ccs_pdaf_pix_loc_block_desc) *
					  num_block_descs);
			if (!(*pdaf)->block_desc_groups[i].block_descs)
				return -ENOMEM;
		} else {
			bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_block_desc) *
				    num_block_descs);
		}

		for (j = 0; j < num_block_descs; j++, __bdesc++) {
			struct ccs_pdaf_pix_loc_block_desc *bdesc;

			if (!is_contained(__bdesc, endp))
				return -ENODATA;

			if (max_block_type_id <= __bdesc->block_type_id)
				max_block_type_id = __bdesc->block_type_id + 1;

			if (!bin->base)
				continue;

			bdesc = &(*pdaf)->block_desc_groups[i].block_descs[j];

			bdesc->repeat_x = ((u16)__bdesc->repeat_x[0] << 8)
				+ __bdesc->repeat_x[1];

			if (__bdesc->block_type_id >= num_block_descs)
				return -EINVAL;

			bdesc->block_type_id = __bdesc->block_type_id;
		}

		__bdesc_group = (const void *)__bdesc;
	}

	__num_pixel_descs = (const void *)__bdesc_group;

	if (bin->base) {
		(*pdaf)->pixel_desc_groups =
			bin_alloc(bin,
				  sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) *
				  max_block_type_id);
		if (!(*pdaf)->pixel_desc_groups)
			return -ENOMEM;
		(*pdaf)->num_pixel_desc_grups = max_block_type_id;
	} else {
		bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group) *
			    max_block_type_id);
	}

	for (i = 0; i < max_block_type_id; i++) {
		struct ccs_pdaf_pix_loc_pixel_desc_group *pdgroup = NULL;
		unsigned int j;

		if (!is_contained(__num_pixel_descs, endp))
			return -ENODATA;

		if (bin->base) {
			pdgroup = &(*pdaf)->pixel_desc_groups[i];
			pdgroup->descs =
				bin_alloc(bin,
					  sizeof(struct ccs_pdaf_pix_loc_pixel_desc) *
					  *__num_pixel_descs);
			if (!pdgroup->descs)
				return -ENOMEM;
			pdgroup->num_descs = *__num_pixel_descs;
		} else {
			bin_reserve(bin, sizeof(struct ccs_pdaf_pix_loc_pixel_desc) *
				    *__num_pixel_descs);
		}

		__pixel_desc = (const void *)(__num_pixel_descs + 1);

		for (j = 0; j < *__num_pixel_descs; j++, __pixel_desc++) {
			struct ccs_pdaf_pix_loc_pixel_desc *pdesc;

			if (!is_contained(__pixel_desc, endp))
				return -ENODATA;

			if (!bin->base)
				continue;

			if (!pdgroup)
				return -EIO;

			pdesc = &pdgroup->descs[j];
			pdesc->pixel_type = __pixel_desc->pixel_type;
			pdesc->small_offset_x = __pixel_desc->small_offset_x;
			pdesc->small_offset_y = __pixel_desc->small_offset_y;
		}

		__num_pixel_descs = (const void *)(__pixel_desc + 1);
	}

	return 0;
}

static int ccs_data_parse_license(struct bin_container *bin,
				  char **__license,
				  size_t *__license_length,
				  const void *payload, const void *endp)
{
	size_t size = endp - payload;
	char *license;

	if (!bin->base) {
		bin_reserve(bin, size);
		return 0;
	}

	license = bin_alloc(bin, size);
	if (!license)
		return -ENOMEM;

	memcpy(license, payload, size);

	*__license = license;
	*__license_length = size;

	return 0;
}

static int ccs_data_parse_end(bool *end, const void *payload, const void *endp,
			      struct device *dev)
{
	const struct __ccs_data_block_end *__end = payload;

	if (__end + 1 != endp) {
		dev_dbg(dev, "Invalid end block length %u\n",
			(unsigned int)(endp - payload));
		return -ENODATA;
	}

	*end = true;

	return 0;
}

static int __ccs_data_parse(struct bin_container *bin,
			    struct ccs_data_container *ccsdata,
			    const void *data, size_t len, struct device *dev,
			    bool verbose)
{
	const struct __ccs_data_block *block = data;
	const struct __ccs_data_block *endp = data + len;
	unsigned int version;
	bool is_first = true;
	int rval;

	version = ccs_data_parse_format_version(block);
	if (version != CCS_STATIC_DATA_VERSION) {
		dev_dbg(dev, "Don't know how to handle version %u\n", version);
		return -EINVAL;
	}

	if (verbose)
		dev_dbg(dev, "Parsing CCS static data version %u\n", version);

	if (!bin->base)
		*ccsdata = (struct ccs_data_container){ 0 };

	while (block < endp) {
		const struct __ccs_data_block *next_block;
		unsigned int block_id;
		const void *payload;

		rval = ccs_data_block_parse_header(block, is_first, &block_id,
						   &payload, &next_block, endp,
						   dev,
						   bin->base ? false : verbose);

		if (rval < 0)
			return rval;

		switch (block_id) {
		case CCS_DATA_BLOCK_ID_DUMMY:
			break;
		case CCS_DATA_BLOCK_ID_DATA_VERSION:
			rval = ccs_data_parse_version(bin, ccsdata, payload,
						      next_block);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->sensor_read_only_regs,
				&ccsdata->num_sensor_read_only_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->sensor_manufacturer_regs,
				&ccsdata->num_sensor_manufacturer_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->module_read_only_regs,
				&ccsdata->num_module_read_only_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS:
			rval = ccs_data_parse_regs(
				bin, &ccsdata->module_manufacturer_regs,
				&ccsdata->num_module_manufacturer_regs, payload,
				next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION:
			rval = ccs_data_parse_pdaf(bin, &ccsdata->sensor_pdaf,
						   payload, next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION:
			rval = ccs_data_parse_pdaf(bin, &ccsdata->module_pdaf,
						   payload, next_block, dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK:
			rval = ccs_data_parse_rules(
				bin, &ccsdata->sensor_rules,
				&ccsdata->num_sensor_rules, payload, next_block,
				dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK:
			rval = ccs_data_parse_rules(
				bin, &ccsdata->module_rules,
				&ccsdata->num_module_rules, payload, next_block,
				dev);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_LICENSE:
			rval = ccs_data_parse_license(bin, &ccsdata->license,
						      &ccsdata->license_length,
						      payload, next_block);
			if (rval < 0)
				return rval;
			break;
		case CCS_DATA_BLOCK_ID_END:
			rval = ccs_data_parse_end(&ccsdata->end, payload,
						  next_block, dev);
			if (rval < 0)
				return rval;
			break;
		default:
			dev_dbg(dev, "WARNING: not handling block ID 0x%2.2x\n",
				block_id);
		}

		block = next_block;
		is_first = false;
	}

	return 0;
}

/**
 * ccs_data_parse - Parse a CCS static data file into a usable in-memory
 *		    data structure
 * @ccsdata:	CCS static data in-memory data structure
 * @data:	CCS static data binary
 * @len:	Length of @data
 * @dev:	Device the data is related to (used for printing debug messages)
 * @verbose:	Whether to be verbose or not
 */
int ccs_data_parse(struct ccs_data_container *ccsdata, const void *data,
		   size_t len, struct device *dev, bool verbose)
{
	struct bin_container bin = { 0 };
	int rval;

	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose);
	if (rval)
		return rval;

	rval = bin_backing_alloc(&bin);
	if (rval)
		return rval;

	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false);
	if (rval)
		goto out_free;

	if (verbose && ccsdata->version)
		print_ccs_data_version(dev, ccsdata->version);

	if (bin.now != bin.end) {
		rval = -EPROTO;
		dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n",
			bin.base, bin.now, bin.end);
		goto out_free;
	}

	ccsdata->backing = bin.base;

	return 0;

out_free:
	kvfree(bin.base);

	return rval;
}
