File: nvmem.h

package info (click to toggle)
optee-os 4.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,960 kB
  • sloc: ansic: 444,388; asm: 12,922; python: 3,719; makefile: 1,681; sh: 238
file content (193 lines) | stat: -rw-r--r-- 5,678 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* SPDX-License-Identifier: BSD-2-Clause */
/*
 * Copyright (c) 2023, Microchip
 */

#ifndef __DRIVERS_NVMEM_H
#define __DRIVERS_NVMEM_H

#include <kernel/dt_driver.h>
#include <tee_api_defines.h>
#include <tee_api_types.h>
#include <types_ext.h>

struct nvmem_cell;

/*
 * struct nvmem_ops - NVMEM device driver operations
 * @read_cell: Allocate @data in the heap and load @len bytes to from an
 * NVMEM cell
 * @put_cell: Release resources allocated from nvmem_dt_get_func callback
 * function
 */
struct nvmem_ops {
	/*
	 * Read data from an NVMEM cell.
	 * @cell: Cell to read data from
	 * @data: Output buffer of size greater or equal to @cell->size
	 */
	TEE_Result (*read_cell)(struct nvmem_cell *cell, uint8_t *data);
	void (*put_cell)(struct nvmem_cell *cell);
};

/*
 * struct nvmem_cell - Description of an NVMEM cell
 * @offset: Cell byte offset in the NVMEM device
 * @len: Cell byte size
 * @ops: NVMEM device driver operation handlers
 * @drv_data: NVMEM device driver private data
 */
struct nvmem_cell {
	paddr_t offset;
	size_t len;
	const struct nvmem_ops *ops;
	void *drv_data;
};

/*
 * nvmem_dt_get_func - Typedef of handlers to get an NVMEM cell from a npode
 * @args: Reference to phandle arguments
 * @data: Pointer to data given at nvmem_dt_get_func() call
 * @cell: Output reference to cell instance upon success
 *
 * Return TEE_SUCCESS in case of success.
 * Return TEE_ERROR_DEFER_DRIVER_INIT if NVMEM driver is not initialized
 * Return another TEE_Result compliant code otherwise.
 */
typedef TEE_Result (*nvmem_dt_get_func)(struct dt_pargs *args,
					void *data, struct nvmem_cell **cell);

#ifdef CFG_DRIVERS_NVMEM
/**
 * nvmem_register_provider() - Register a NVMEM controller
 *
 * @fdt: Device tree to work on
 * @nodeoffset: Node offset of NVMEM cell consumer
 * @get_dt_nvmem: Callback to match the devicetree NVMEM reference with
 * nvmem_cell
 * @data: Data which will be passed to the get_dt_nvmem callback
 * Return a TEE_Result compliant value
 */
static inline TEE_Result nvmem_register_provider(const void *fdt,
						 int nodeoffset,
						 nvmem_dt_get_func get_dt_nvmem,
						 void *data)
{
	return dt_driver_register_provider(fdt, nodeoffset,
					   (get_of_device_func)get_dt_nvmem,
					   data, DT_DRIVER_NVMEM);
}

/**
 * nvmem_get_cell_by_name() - Obtain a NVMEM cell from its name in the DT node
 *
 * @fdt: Device tree to work on
 * @nodeoffset: Node offset of NVMEM cell consumer
 * @name: name of the NVMEM cell defined by property nvmem-cell-names to obtain
 * from the device tree
 * @cell: Pointer filled with the retrieved cell, must be freed after use
   using nvmem_put_cell()
 * Return a TEE_Result compliant value
 */
TEE_Result nvmem_get_cell_by_name(const void *fdt, int nodeoffset,
				  const char *name, struct nvmem_cell **cell);

/**
 * nvmem_get_cell_by_index() - Obtain a NVMEM cell from property nvmem-cells
 *
 * @fdt: Device tree to work on
 * @nodeoffset: Node offset of NVMEM cell consumer
 * @index: Index of the NVMEM cell to obtain from device-tree
 * @out_cell: Pointer filled with the retrieved cell, must be freed after use
 * using nvmem_put_cell()
 * Return a TEE_Result compliant value
 */
TEE_Result nvmem_get_cell_by_index(const void *fdt,
				   int nodeoffset,
				   unsigned int index,
				   struct nvmem_cell **out_cell);

/**
 * nvmem_cell_parse_dt() - Parse device-tree information to fill a NVMEM cell
 *
 * @fdt: Device tree to work on
 * @nodeoffset: Node offset of the NVMEM cell controller
 * @cell: Pointer to cell that will be filled
 */
TEE_Result nvmem_cell_parse_dt(const void *fdt, int nodeoffset,
			       struct nvmem_cell *cell);

/**
 * nvmem_put_cell() - Free resource allocated from nvmem_get_cell_by_*()
 *
 * @cell: Cell to be freed
 */
static inline void nvmem_put_cell(struct nvmem_cell *cell)
{
	if (cell->ops->put_cell)
		cell->ops->put_cell(cell);
}

/*
 * nvmem_cell_read() - Read data from a NVMEM cell
 * @cell: Cell to read from NVMEM
 * @data: Output data read from the cell upon success, byte size >= @cell->size
 */
static inline TEE_Result nvmem_cell_read(struct nvmem_cell *cell,
					 uint8_t *data)
{
	if (!cell->ops->read_cell)
		return TEE_ERROR_NOT_SUPPORTED;

	return cell->ops->read_cell(cell, data);
}

/*
 * nvmem_cell_malloc_and_read() - Allocate and read data from a NVMEM cell
 * @cell: Cell to read from NVMEM
 * @data: Output allocated buffer where NVMEM cell data are stored upon success
 *
 * Upon success, the output buffer is allocated with malloc(). Caller is
 * responsible for freeing the buffer with free() if needed.
 */
TEE_Result nvmem_cell_malloc_and_read(struct nvmem_cell *cell,
				      uint8_t **out_data);

#else /* CFG_DRIVERS_NVMEM */
static inline TEE_Result nvmem_register_provider(const void *fdt __unused,
						 int nodeoffset __unused,
						 nvmem_dt_get_func fn __unused,
						 void *data __unused)
{
	return TEE_ERROR_NOT_SUPPORTED;
}

static inline TEE_Result nvmem_get_cell_by_name(const void *fdt __unused,
						int nodeoffset __unused,
						const char *name __unused,
						struct nvmem_cell **c __unused)
{
	return TEE_ERROR_NOT_SUPPORTED;
}

static inline
TEE_Result nvmem_get_cell_by_index(const void *fdt __unused,
				   int nodeoffset __unused,
				   unsigned int index __unused,
				   struct nvmem_cell **cell __unused)
{
	return TEE_ERROR_NOT_SUPPORTED;
}

static inline TEE_Result nvmem_cell_parse_dt(const void *fdt __unused,
					     int nodeoffset __unused,
					     struct nvmem_cell *cell __unused)
{
	return TEE_ERROR_NOT_SUPPORTED;
}

static inline void nvmem_put_cell(struct nvmem_cell *cell __unused)
{
}
#endif /* CFG_DRIVERS_NVMEM */
#endif /* __DRIVERS_NVMEM_H */