1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * CCS static data binary parser library
5 * Copyright 2019--2020 Intel Corporation
8 #include <linux/device.h>
9 #include <linux/errno.h>
10 #include <linux/limits.h>
12 #include <linux/slab.h>
13 #include <linux/types.h>
15 #include "ccs-data-defs.h"
17 struct bin_container
{
24 static void *bin_alloc(struct bin_container
*bin
, size_t len
)
30 if (bin
->end
- bin
->now
< len
)
39 static void bin_reserve(struct bin_container
*bin
, size_t len
)
41 bin
->size
+= ALIGN(len
, 8);
44 static int bin_backing_alloc(struct bin_container
*bin
)
46 bin
->base
= bin
->now
= kvzalloc(bin
->size
, GFP_KERNEL
);
50 bin
->end
= bin
->base
+ bin
->size
;
55 #define is_contained(var, endp) \
56 (sizeof(*var) <= (endp) - (void *)(var))
57 #define has_headroom(ptr, headroom, endp) \
58 ((headroom) <= (endp) - (void *)(ptr))
59 #define is_contained_with_headroom(var, headroom, endp) \
60 (sizeof(*var) + (headroom) <= (endp) - (void *)(var))
63 ccs_data_parse_length_specifier(const struct __ccs_data_length_specifier
*__len
,
64 size_t *__hlen
, size_t *__plen
,
69 if (!is_contained(__len
, endp
))
72 switch (__len
->length
>> CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) {
73 case CCS_DATA_LENGTH_SPECIFIER_1
:
74 hlen
= sizeof(*__len
);
75 plen
= __len
->length
&
76 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1);
78 case CCS_DATA_LENGTH_SPECIFIER_2
: {
79 struct __ccs_data_length_specifier2
*__len2
= (void *)__len
;
81 if (!is_contained(__len2
, endp
))
84 hlen
= sizeof(*__len2
);
87 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1))
88 << 8) + __len2
->length
[1];
91 case CCS_DATA_LENGTH_SPECIFIER_3
: {
92 struct __ccs_data_length_specifier3
*__len3
= (void *)__len
;
94 if (!is_contained(__len3
, endp
))
97 hlen
= sizeof(*__len3
);
100 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT
) - 1))
101 << 16) + (__len3
->length
[0] << 8) + __len3
->length
[1];
108 if (!has_headroom(__len
, hlen
+ plen
, endp
))
118 ccs_data_parse_format_version(const struct __ccs_data_block
*block
)
120 return block
->id
>> CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT
;
123 static u8
ccs_data_parse_block_id(const struct __ccs_data_block
*block
,
129 return block
->id
& ((1 << CCS_DATA_BLOCK_HEADER_ID_VERSION_SHIFT
) - 1);
132 static int ccs_data_parse_version(struct bin_container
*bin
,
133 struct ccs_data_container
*ccsdata
,
134 const void *payload
, const void *endp
)
136 const struct __ccs_data_block_version
*v
= payload
;
137 struct ccs_data_block_version
*vv
;
143 bin_reserve(bin
, sizeof(*ccsdata
->version
));
147 ccsdata
->version
= bin_alloc(bin
, sizeof(*ccsdata
->version
));
148 if (!ccsdata
->version
)
151 vv
= ccsdata
->version
;
152 vv
->version_major
= ((u16
)v
->static_data_version_major
[0] << 8) +
153 v
->static_data_version_major
[1];
154 vv
->version_minor
= ((u16
)v
->static_data_version_minor
[0] << 8) +
155 v
->static_data_version_major
[1];
156 vv
->date_year
= ((u16
)v
->year
[0] << 8) + v
->year
[1];
157 vv
->date_month
= v
->month
;
158 vv
->date_day
= v
->day
;
163 static void print_ccs_data_version(struct device
*dev
,
164 struct ccs_data_block_version
*v
)
167 "static data version %4.4x.%4.4x, date %4.4u-%2.2u-%2.2u\n",
168 v
->version_major
, v
->version_minor
,
169 v
->date_year
, v
->date_month
, v
->date_day
);
172 static int ccs_data_block_parse_header(const struct __ccs_data_block
*block
,
173 bool is_first
, unsigned int *__block_id
,
174 const void **payload
,
175 const struct __ccs_data_block
**next_block
,
176 const void *endp
, struct device
*dev
,
183 if (!is_contained(block
, endp
))
186 rval
= ccs_data_parse_length_specifier(&block
->length
, &hlen
, &plen
,
191 block_id
= ccs_data_parse_block_id(block
, is_first
);
195 "Block ID 0x%2.2x, header length %zu, payload length %zu\n",
196 block_id
, hlen
, plen
);
198 if (!has_headroom(&block
->length
, hlen
+ plen
, endp
))
202 *__block_id
= block_id
;
205 *payload
= (void *)&block
->length
+ hlen
;
208 *next_block
= (void *)&block
->length
+ hlen
+ plen
;
213 static int ccs_data_parse_regs(struct bin_container
*bin
,
214 struct ccs_reg
**__regs
,
215 size_t *__num_regs
, const void *payload
,
216 const void *endp
, struct device
*dev
)
218 struct ccs_reg
*regs_base
, *regs
;
222 if (bin
->base
&& __regs
) {
223 regs
= regs_base
= bin_alloc(bin
, sizeof(*regs
) * *__num_regs
);
228 while (payload
< endp
&& num_regs
< INT_MAX
) {
229 const struct __ccs_data_block_regs
*r
= payload
;
233 if (!is_contained(r
, endp
))
236 switch (r
->reg_len
>> CCS_DATA_BLOCK_REGS_SEL_SHIFT
) {
237 case CCS_DATA_BLOCK_REGS_SEL_REGS
:
238 addr
+= r
->reg_len
& CCS_DATA_BLOCK_REGS_ADDR_MASK
;
239 len
= ((r
->reg_len
& CCS_DATA_BLOCK_REGS_LEN_MASK
)
240 >> CCS_DATA_BLOCK_REGS_LEN_SHIFT
) + 1;
242 if (!is_contained_with_headroom(r
, len
, endp
))
247 case CCS_DATA_BLOCK_REGS_SEL_REGS2
: {
248 const struct __ccs_data_block_regs2
*r2
= payload
;
250 if (!is_contained(r2
, endp
))
253 addr
+= ((u16
)(r2
->reg_len
&
254 CCS_DATA_BLOCK_REGS_2_ADDR_MASK
) << 8)
256 len
= ((r2
->reg_len
& CCS_DATA_BLOCK_REGS_2_LEN_MASK
)
257 >> CCS_DATA_BLOCK_REGS_2_LEN_SHIFT
) + 1;
259 if (!is_contained_with_headroom(r2
, len
, endp
))
265 case CCS_DATA_BLOCK_REGS_SEL_REGS3
: {
266 const struct __ccs_data_block_regs3
*r3
= payload
;
268 if (!is_contained(r3
, endp
))
271 addr
= ((u16
)r3
->addr
[0] << 8) + r3
->addr
[1];
272 len
= (r3
->reg_len
& CCS_DATA_BLOCK_REGS_3_LEN_MASK
) + 1;
274 if (!is_contained_with_headroom(r3
, len
, endp
))
287 bin_reserve(bin
, len
);
291 regs
->value
= bin_alloc(bin
, len
);
295 memcpy(regs
->value
, data
, len
);
300 payload
= data
+ len
;
304 bin_reserve(bin
, sizeof(*regs
) * num_regs
);
307 *__num_regs
= num_regs
;
309 if (bin
->base
&& __regs
)
315 static int ccs_data_parse_reg_rules(struct bin_container
*bin
,
316 struct ccs_reg
**__regs
,
319 const void *endp
, struct device
*dev
)
324 return ccs_data_parse_regs(bin
, NULL
, NULL
, payload
, endp
, dev
);
326 rval
= ccs_data_parse_regs(bin
, NULL
, __num_regs
, payload
, endp
, dev
);
330 return ccs_data_parse_regs(bin
, __regs
, __num_regs
, payload
, endp
,
334 static void assign_ffd_entry(struct ccs_frame_format_desc
*desc
,
335 const struct __ccs_data_block_ffd_entry
*ent
)
337 desc
->pixelcode
= ent
->pixelcode
;
338 desc
->value
= ((u16
)ent
->value
[0] << 8) + ent
->value
[1];
341 static int ccs_data_parse_ffd(struct bin_container
*bin
,
342 struct ccs_frame_format_descs
**ffd
,
344 const void *endp
, struct device
*dev
)
346 const struct __ccs_data_block_ffd
*__ffd
= payload
;
347 const struct __ccs_data_block_ffd_entry
*__entry
;
350 if (!is_contained(__ffd
, endp
))
353 if ((void *)__ffd
+ sizeof(*__ffd
) +
354 ((u32
)__ffd
->num_column_descs
+
355 (u32
)__ffd
->num_row_descs
) *
356 sizeof(struct __ccs_data_block_ffd_entry
) != endp
)
360 bin_reserve(bin
, sizeof(**ffd
));
361 bin_reserve(bin
, __ffd
->num_column_descs
*
362 sizeof(struct ccs_frame_format_desc
));
363 bin_reserve(bin
, __ffd
->num_row_descs
*
364 sizeof(struct ccs_frame_format_desc
));
369 *ffd
= bin_alloc(bin
, sizeof(**ffd
));
373 (*ffd
)->num_column_descs
= __ffd
->num_column_descs
;
374 (*ffd
)->num_row_descs
= __ffd
->num_row_descs
;
375 __entry
= (void *)(__ffd
+ 1);
377 (*ffd
)->column_descs
= bin_alloc(bin
, __ffd
->num_column_descs
*
378 sizeof(*(*ffd
)->column_descs
));
379 if (!(*ffd
)->column_descs
)
382 for (i
= 0; i
< __ffd
->num_column_descs
; i
++, __entry
++)
383 assign_ffd_entry(&(*ffd
)->column_descs
[i
], __entry
);
385 (*ffd
)->row_descs
= bin_alloc(bin
, __ffd
->num_row_descs
*
386 sizeof(*(*ffd
)->row_descs
));
387 if (!(*ffd
)->row_descs
)
390 for (i
= 0; i
< __ffd
->num_row_descs
; i
++, __entry
++)
391 assign_ffd_entry(&(*ffd
)->row_descs
[i
], __entry
);
399 static int ccs_data_parse_pdaf_readout(struct bin_container
*bin
,
400 struct ccs_pdaf_readout
**pdaf_readout
,
402 const void *endp
, struct device
*dev
)
404 const struct __ccs_data_block_pdaf_readout
*__pdaf
= payload
;
406 if (!is_contained(__pdaf
, endp
))
410 bin_reserve(bin
, sizeof(**pdaf_readout
));
412 *pdaf_readout
= bin_alloc(bin
, sizeof(**pdaf_readout
));
416 (*pdaf_readout
)->pdaf_readout_info_order
=
417 __pdaf
->pdaf_readout_info_order
;
420 return ccs_data_parse_ffd(bin
, !bin
->base
? NULL
: &(*pdaf_readout
)->ffd
,
421 __pdaf
+ 1, endp
, dev
);
424 static int ccs_data_parse_rules(struct bin_container
*bin
,
425 struct ccs_rule
**__rules
,
426 size_t *__num_rules
, const void *payload
,
427 const void *endp
, struct device
*dev
)
429 struct ccs_rule
*rules_base
, *rules
= NULL
, *next_rule
;
430 size_t num_rules
= 0;
431 const void *__next_rule
= payload
;
435 rules_base
= next_rule
=
436 bin_alloc(bin
, sizeof(*rules
) * *__num_rules
);
441 while (__next_rule
< endp
) {
442 size_t rule_hlen
, rule_plen
, rule_plen2
;
443 const u8
*__rule_type
;
444 const void *rule_payload
;
446 /* Size of a single rule */
447 rval
= ccs_data_parse_length_specifier(__next_rule
, &rule_hlen
,
453 __rule_type
= __next_rule
+ rule_hlen
;
455 if (!is_contained(__rule_type
, endp
))
458 rule_payload
= __rule_type
+ 1;
459 rule_plen2
= rule_plen
- sizeof(*__rule_type
);
461 switch (*__rule_type
) {
462 case CCS_DATA_BLOCK_RULE_ID_IF
: {
463 const struct __ccs_data_block_rule_if
*__if_rules
=
465 const size_t __num_if_rules
=
466 rule_plen2
/ sizeof(*__if_rules
);
467 struct ccs_if_rule
*if_rule
;
469 if (!has_headroom(__if_rules
,
470 sizeof(*__if_rules
) * __num_if_rules
,
471 rule_payload
+ rule_plen2
))
474 /* Also check there is no extra data */
475 if (__if_rules
+ __num_if_rules
!=
476 rule_payload
+ rule_plen2
)
490 if_rule
= bin_alloc(bin
,
496 for (i
= 0; i
< __num_if_rules
; i
++) {
498 ((u16
)__if_rules
[i
].addr
[0]
500 __if_rules
[i
].addr
[1];
501 if_rule
[i
].value
= __if_rules
[i
].value
;
502 if_rule
[i
].mask
= __if_rules
[i
].mask
;
505 rules
->if_rules
= if_rule
;
506 rules
->num_if_rules
= __num_if_rules
;
510 case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS
:
511 rval
= ccs_data_parse_reg_rules(bin
, &rules
->read_only_regs
,
512 &rules
->num_read_only_regs
,
514 rule_payload
+ rule_plen2
,
519 case CCS_DATA_BLOCK_RULE_ID_FFD
:
520 rval
= ccs_data_parse_ffd(bin
, &rules
->frame_format
,
522 rule_payload
+ rule_plen2
,
527 case CCS_DATA_BLOCK_RULE_ID_MSR
:
528 rval
= ccs_data_parse_reg_rules(bin
,
529 &rules
->manufacturer_regs
,
530 &rules
->num_manufacturer_regs
,
532 rule_payload
+ rule_plen2
,
537 case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT
:
538 rval
= ccs_data_parse_pdaf_readout(bin
,
539 &rules
->pdaf_readout
,
541 rule_payload
+ rule_plen2
,
548 "Don't know how to handle rule type %u!\n",
552 __next_rule
= __next_rule
+ rule_hlen
+ rule_plen
;
556 bin_reserve(bin
, sizeof(*rules
) * num_rules
);
557 *__num_rules
= num_rules
;
559 *__rules
= rules_base
;
565 static int ccs_data_parse_pdaf(struct bin_container
*bin
, struct ccs_pdaf_pix_loc
**pdaf
,
566 const void *payload
, const void *endp
,
569 const struct __ccs_data_block_pdaf_pix_loc
*__pdaf
= payload
;
570 const struct __ccs_data_block_pdaf_pix_loc_block_desc_group
*__bdesc_group
;
571 const struct __ccs_data_block_pdaf_pix_loc_pixel_desc
*__pixel_desc
;
573 u16 num_block_desc_groups
;
574 u8 max_block_type_id
= 0;
575 const u8
*__num_pixel_descs
;
577 if (!is_contained(__pdaf
, endp
))
581 *pdaf
= bin_alloc(bin
, sizeof(**pdaf
));
585 bin_reserve(bin
, sizeof(**pdaf
));
588 num_block_desc_groups
=
589 ((u16
)__pdaf
->num_block_desc_groups
[0] << 8) +
590 __pdaf
->num_block_desc_groups
[1];
593 (*pdaf
)->main_offset_x
=
594 ((u16
)__pdaf
->main_offset_x
[0] << 8) +
595 __pdaf
->main_offset_x
[1];
596 (*pdaf
)->main_offset_y
=
597 ((u16
)__pdaf
->main_offset_y
[0] << 8) +
598 __pdaf
->main_offset_y
[1];
599 (*pdaf
)->global_pdaf_type
= __pdaf
->global_pdaf_type
;
600 (*pdaf
)->block_width
= __pdaf
->block_width
;
601 (*pdaf
)->block_height
= __pdaf
->block_height
;
602 (*pdaf
)->num_block_desc_groups
= num_block_desc_groups
;
605 __bdesc_group
= (const void *)(__pdaf
+ 1);
608 (*pdaf
)->block_desc_groups
=
610 sizeof(struct ccs_pdaf_pix_loc_block_desc_group
) *
611 num_block_desc_groups
);
612 if (!(*pdaf
)->block_desc_groups
)
615 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_block_desc_group
) *
616 num_block_desc_groups
);
619 for (i
= 0; i
< num_block_desc_groups
; i
++) {
620 const struct __ccs_data_block_pdaf_pix_loc_block_desc
*__bdesc
;
624 if (!is_contained(__bdesc_group
, endp
))
628 ((u16
)__bdesc_group
->num_block_descs
[0] << 8) +
629 __bdesc_group
->num_block_descs
[1];
632 (*pdaf
)->block_desc_groups
[i
].repeat_y
=
633 __bdesc_group
->repeat_y
;
634 (*pdaf
)->block_desc_groups
[i
].num_block_descs
=
638 __bdesc
= (const void *)(__bdesc_group
+ 1);
641 (*pdaf
)->block_desc_groups
[i
].block_descs
=
643 sizeof(struct ccs_pdaf_pix_loc_block_desc
) *
645 if (!(*pdaf
)->block_desc_groups
[i
].block_descs
)
648 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_block_desc
) *
652 for (j
= 0; j
< num_block_descs
; j
++, __bdesc
++) {
653 struct ccs_pdaf_pix_loc_block_desc
*bdesc
;
655 if (!is_contained(__bdesc
, endp
))
658 if (max_block_type_id
<= __bdesc
->block_type_id
)
659 max_block_type_id
= __bdesc
->block_type_id
+ 1;
664 bdesc
= &(*pdaf
)->block_desc_groups
[i
].block_descs
[j
];
666 bdesc
->repeat_x
= ((u16
)__bdesc
->repeat_x
[0] << 8)
667 + __bdesc
->repeat_x
[1];
669 if (__bdesc
->block_type_id
>= num_block_descs
)
672 bdesc
->block_type_id
= __bdesc
->block_type_id
;
675 __bdesc_group
= (const void *)__bdesc
;
678 __num_pixel_descs
= (const void *)__bdesc_group
;
681 (*pdaf
)->pixel_desc_groups
=
683 sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group
) *
685 if (!(*pdaf
)->pixel_desc_groups
)
687 (*pdaf
)->num_pixel_desc_grups
= max_block_type_id
;
689 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_pixel_desc_group
) *
693 for (i
= 0; i
< max_block_type_id
; i
++) {
694 struct ccs_pdaf_pix_loc_pixel_desc_group
*pdgroup
;
697 if (!is_contained(__num_pixel_descs
, endp
))
701 pdgroup
= &(*pdaf
)->pixel_desc_groups
[i
];
704 sizeof(struct ccs_pdaf_pix_loc_pixel_desc
) *
708 pdgroup
->num_descs
= *__num_pixel_descs
;
710 bin_reserve(bin
, sizeof(struct ccs_pdaf_pix_loc_pixel_desc
) *
714 __pixel_desc
= (const void *)(__num_pixel_descs
+ 1);
716 for (j
= 0; j
< *__num_pixel_descs
; j
++, __pixel_desc
++) {
717 struct ccs_pdaf_pix_loc_pixel_desc
*pdesc
;
719 if (!is_contained(__pixel_desc
, endp
))
725 pdesc
= &pdgroup
->descs
[j
];
726 pdesc
->pixel_type
= __pixel_desc
->pixel_type
;
727 pdesc
->small_offset_x
= __pixel_desc
->small_offset_x
;
728 pdesc
->small_offset_y
= __pixel_desc
->small_offset_y
;
731 __num_pixel_descs
= (const void *)(__pixel_desc
+ 1);
737 static int ccs_data_parse_license(struct bin_container
*bin
,
739 size_t *__license_length
,
740 const void *payload
, const void *endp
)
742 size_t size
= endp
- payload
;
746 bin_reserve(bin
, size
);
750 license
= bin_alloc(bin
, size
);
754 memcpy(license
, payload
, size
);
756 *__license
= license
;
757 *__license_length
= size
;
762 static int ccs_data_parse_end(bool *end
, const void *payload
, const void *endp
,
765 const struct __ccs_data_block_end
*__end
= payload
;
767 if (__end
+ 1 != endp
) {
768 dev_dbg(dev
, "Invalid end block length %u\n",
769 (unsigned int)(endp
- payload
));
778 static int __ccs_data_parse(struct bin_container
*bin
,
779 struct ccs_data_container
*ccsdata
,
780 const void *data
, size_t len
, struct device
*dev
,
783 const struct __ccs_data_block
*block
= data
;
784 const struct __ccs_data_block
*endp
= data
+ len
;
785 unsigned int version
;
786 bool is_first
= true;
789 version
= ccs_data_parse_format_version(block
);
790 if (version
!= CCS_STATIC_DATA_VERSION
) {
791 dev_dbg(dev
, "Don't know how to handle version %u\n", version
);
796 dev_dbg(dev
, "Parsing CCS static data version %u\n", version
);
799 *ccsdata
= (struct ccs_data_container
){ 0 };
801 while (block
< endp
) {
802 const struct __ccs_data_block
*next_block
;
803 unsigned int block_id
;
806 rval
= ccs_data_block_parse_header(block
, is_first
, &block_id
,
807 &payload
, &next_block
, endp
,
809 bin
->base
? false : verbose
);
815 case CCS_DATA_BLOCK_ID_DUMMY
:
817 case CCS_DATA_BLOCK_ID_DATA_VERSION
:
818 rval
= ccs_data_parse_version(bin
, ccsdata
, payload
,
823 case CCS_DATA_BLOCK_ID_SENSOR_READ_ONLY_REGS
:
824 rval
= ccs_data_parse_regs(
825 bin
, &ccsdata
->sensor_read_only_regs
,
826 &ccsdata
->num_sensor_read_only_regs
, payload
,
831 case CCS_DATA_BLOCK_ID_SENSOR_MANUFACTURER_REGS
:
832 rval
= ccs_data_parse_regs(
833 bin
, &ccsdata
->sensor_manufacturer_regs
,
834 &ccsdata
->num_sensor_manufacturer_regs
, payload
,
839 case CCS_DATA_BLOCK_ID_MODULE_READ_ONLY_REGS
:
840 rval
= ccs_data_parse_regs(
841 bin
, &ccsdata
->module_read_only_regs
,
842 &ccsdata
->num_module_read_only_regs
, payload
,
847 case CCS_DATA_BLOCK_ID_MODULE_MANUFACTURER_REGS
:
848 rval
= ccs_data_parse_regs(
849 bin
, &ccsdata
->module_manufacturer_regs
,
850 &ccsdata
->num_module_manufacturer_regs
, payload
,
855 case CCS_DATA_BLOCK_ID_SENSOR_PDAF_PIXEL_LOCATION
:
856 rval
= ccs_data_parse_pdaf(bin
, &ccsdata
->sensor_pdaf
,
857 payload
, next_block
, dev
);
861 case CCS_DATA_BLOCK_ID_MODULE_PDAF_PIXEL_LOCATION
:
862 rval
= ccs_data_parse_pdaf(bin
, &ccsdata
->module_pdaf
,
863 payload
, next_block
, dev
);
867 case CCS_DATA_BLOCK_ID_SENSOR_RULE_BASED_BLOCK
:
868 rval
= ccs_data_parse_rules(
869 bin
, &ccsdata
->sensor_rules
,
870 &ccsdata
->num_sensor_rules
, payload
, next_block
,
875 case CCS_DATA_BLOCK_ID_MODULE_RULE_BASED_BLOCK
:
876 rval
= ccs_data_parse_rules(
877 bin
, &ccsdata
->module_rules
,
878 &ccsdata
->num_module_rules
, payload
, next_block
,
883 case CCS_DATA_BLOCK_ID_LICENSE
:
884 rval
= ccs_data_parse_license(bin
, &ccsdata
->license
,
885 &ccsdata
->license_length
,
886 payload
, next_block
);
890 case CCS_DATA_BLOCK_ID_END
:
891 rval
= ccs_data_parse_end(&ccsdata
->end
, payload
,
897 dev_dbg(dev
, "WARNING: not handling block ID 0x%2.2x\n",
909 * ccs_data_parse - Parse a CCS static data file into a usable in-memory
911 * @ccsdata: CCS static data in-memory data structure
912 * @data: CCS static data binary
913 * @len: Length of @data
914 * @dev: Device the data is related to (used for printing debug messages)
915 * @verbose: Whether to be verbose or not
917 int ccs_data_parse(struct ccs_data_container
*ccsdata
, const void *data
,
918 size_t len
, struct device
*dev
, bool verbose
)
920 struct bin_container bin
= { 0 };
923 rval
= __ccs_data_parse(&bin
, ccsdata
, data
, len
, dev
, verbose
);
927 rval
= bin_backing_alloc(&bin
);
931 rval
= __ccs_data_parse(&bin
, ccsdata
, data
, len
, dev
, false);
935 if (verbose
&& ccsdata
->version
)
936 print_ccs_data_version(dev
, ccsdata
->version
);
938 if (bin
.now
!= bin
.end
) {
940 dev_dbg(dev
, "parsing mismatch; base %p; now %p; end %p\n",
941 bin
.base
, bin
.now
, bin
.end
);
945 ccsdata
->backing
= bin
.base
;