summaryrefslogtreecommitdiffstats
path: root/src/include/fw_config.h
blob: 1e1652efb6bc8bc4449dc2059eedc0fa0f160050 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __FW_CONFIG__
#define __FW_CONFIG__

#include <device/device.h>
#include <static.h>  /* Provides fw_config definitions from devicetree.cb */
#include <stdbool.h>
#include <stdint.h>

#define UNDEFINED_FW_CONFIG	~((uint64_t)0)

/**
 * struct fw_config - Firmware configuration field and option.
 * @field_name: Name of the field that this option belongs to.
 * @option_name: Name of the option within this field.
 * @mask: Bitmask of the field.
 * @value: Value of the option within the mask.
 */
struct fw_config {
	const char *field_name;
	const char *option_name;
	uint64_t mask;
	uint64_t value;
};

struct fw_config_field {
	const char *field_name;
	uint64_t mask;
};

/* Generate a pointer to a compound literal of the fw_config structure. */
#define FW_CONFIG(__field, __option)	(&(const struct fw_config) {		\
	.field_name = FW_CONFIG_FIELD_##__field##_NAME,				\
	.option_name = FW_CONFIG_FIELD_##__field##_OPTION_##__option##_NAME,	\
	.mask = FW_CONFIG_FIELD_##__field##_MASK,				\
	.value = FW_CONFIG_FIELD_##__field##_OPTION_##__option##_VALUE		\
})

#define FW_CONFIG_FIELD(__field) (&(const struct fw_config_field) {		\
	.field_name = FW_CONFIG_FIELD_##__field##_NAME,				\
	.mask = FW_CONFIG_FIELD_##__field##_MASK,				\
})

/**
 * fw_config_get() - Provide firmware configuration value.
 *
 * Return 64bit firmware configuration value determined for the system.
 */
uint64_t fw_config_get(void);

/**
 * fw_config_is_provisioned() - Determine if FW_CONFIG has been provisioned.
 * Return %true if FW_CONFIG has been provisioned, %false otherwise.
 */
static inline bool fw_config_is_provisioned(void)
{
	return fw_config_get() != UNDEFINED_FW_CONFIG;
}


#if CONFIG(FW_CONFIG)

/**
 * fw_config_get_field() - Provide firmware configuration field value.
 * @field: Structure containing field name and mask
 *
 * Return 64bit firmware configuration value determined for the system.
 * Will return UNDEFINED_FW_CONFIG if unprovisioned, caller should treat
 * as error value for the case.
 */
uint64_t fw_config_get_field(const struct fw_config_field *field);

/**
 * fw_config_probe() - Check if field and option matches.
 * @match: Structure containing field and option to probe.
 *
 * Return %true if match is found, %false if match is not found.
 */
bool fw_config_probe(const struct fw_config *match);

/**
 * fw_config_for_each_found() - Call a callback for each fw_config field found
 * @cb: The callback function
 * @arg: A context argument that is passed to the callback
 */
void fw_config_for_each_found(void (*cb)(const struct fw_config *config, void *arg), void *arg);

/**
 * fw_config_get_found() - Return a pointer to the fw_config struct for a given field.
 * @field_mask: A field mask from static.h, e.g., FW_CONFIG_FIELD_FEATURE_MASK
 *
 * Return pointer to cached `struct fw_config` if successfully probed, otherwise NULL.
*/
const struct fw_config *fw_config_get_found(uint64_t field_mask);

/**
 * fw_config_probe_dev() - Check if any of the probe conditions are true for given device.
 * @dev: Device for which probe conditions are checked
 * @matching_probe: If any probe condition match, then the matching probe condition is returned
 * to the caller.
 * Return %true if device has no probing conditions or if a matching probe condition is
 * encountered, %false otherwise.
 */
bool fw_config_probe_dev(const struct device *dev, const struct fw_config **matching_probe);

#else

static inline bool fw_config_probe(const struct fw_config *match)
{
	/* Always return true when probing with disabled fw_config. */
	return true;
}

static inline bool fw_config_probe_dev(const struct device *dev,
				       const struct fw_config **matching_probe)
{
	/* Always return true when probing with disabled fw_config. */
	if (matching_probe)
		*matching_probe = NULL;
	return true;
}

static inline uint64_t fw_config_get_field(const struct fw_config_field *field)
{
	/* Always return UNDEFINED_FW_CONFIG when get with disabled fw_config. */
	return UNDEFINED_FW_CONFIG;
}

#endif /* CONFIG(FW_CONFIG) */

#endif /* __FW_CONFIG__ */