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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Core ACPI (Advanced Configuration and Power Interface) support
*
* Copyright 2019 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __DM_ACPI_H__
#define __DM_ACPI_H__
/* Allow operations to be optional for ACPI */
#if CONFIG_IS_ENABLED(ACPIGEN)
#define ACPI_OPS_PTR(_ptr) .acpi_ops = _ptr,
#else
#define ACPI_OPS_PTR(_ptr)
#endif
/* Length of an ACPI name string, excluding null terminator */
#define ACPI_NAME_LEN 4
/* Length of an ACPI name string including nul terminator */
#define ACPI_NAME_MAX (ACPI_NAME_LEN + 1)
/* Number of nested objects supported */
#define ACPIGEN_LENSTACK_SIZE 10
#if !defined(__ACPI__)
struct nhlt;
/** enum acpi_dump_option - selects what ACPI information to dump */
enum acpi_dump_option {
ACPI_DUMP_LIST, /* Just the list of items */
ACPI_DUMP_CONTENTS, /* Include the binary contents also */
};
/**
* struct acpi_ctx - Context used for writing ACPI tables
*
* This contains a few useful pieces of information used when writing
*
* @base: Base address of ACPI tables
* @current: Current address for writing
* @rsdp: Pointer to the Root System Description Pointer, typically used when
* adding a new table. The RSDP holds pointers to the RSDT and XSDT.
* @rsdt: Pointer to the Root System Description Table
* @xsdt: Pointer to the Extended System Description Table
* @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to
* build up information that audio codecs need to provide in the NHLT ACPI
* table
* @len_stack: Stack of 'length' words to fix up later
* @ltop: Points to current top of stack (0 = empty)
*/
struct acpi_ctx {
void *base;
void *current;
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
struct acpi_xsdt *xsdt;
struct nhlt *nhlt;
char *len_stack[ACPIGEN_LENSTACK_SIZE];
int ltop;
};
/**
* struct acpi_ops - ACPI operations supported by driver model
*/
struct acpi_ops {
/**
* get_name() - Obtain the ACPI name of a device
*
* @dev: Device to check
* @out_name: Place to put the name, must hold at least ACPI_NAME_MAX
* bytes
* @return 0 if OK, -ENOENT if no name is available, other -ve value on
* other error
*/
int (*get_name)(const struct udevice *dev, char *out_name);
/**
* write_tables() - Write out any tables required by this device
*
* @dev: Device to write
* @ctx: ACPI context to use
* @return 0 if OK, -ve on error
*/
int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx);
/**
* fill_ssdt() - Generate SSDT code for a device
*
* This is called to create the SSDT code. The method should write out
* whatever ACPI code is needed by this device. It will end up in the
* SSDT table.
*
* Note that this is called 'fill' because the entire contents of the
* SSDT is build by calling this method on all devices.
*
* @dev: Device to write
* @ctx: ACPI context to use
* @return 0 if OK, -ve on error
*/
int (*fill_ssdt)(const struct udevice *dev, struct acpi_ctx *ctx);
/**
* inject_dsdt() - Generate DSDT code for a device
*
* This is called to create the DSDT code. The method should write out
* whatever ACPI code is needed by this device. It will end up in the
* DSDT table.
*
* Note that this is called 'inject' because the output of calling this
* method on all devices is injected into the DSDT, the bulk of which
* is written in .asl files for the board.
*
* @dev: Device to write
* @ctx: ACPI context to use
* @return 0 if OK, -ve on error
*/
int (*inject_dsdt)(const struct udevice *dev, struct acpi_ctx *ctx);
/**
* setup_nhlt() - Set up audio information for this device
*
* The method can add information to ctx->nhlt if it likes
*
* @return 0 if OK, -ENODATA if nothing to add, -ve on error
*/
int (*setup_nhlt)(const struct udevice *dev, struct acpi_ctx *ctx);
};
#define device_get_acpi_ops(dev) ((dev)->driver->acpi_ops)
/**
* acpi_get_name() - Obtain the ACPI name of a device
*
* @dev: Device to check
* @out_name: Place to put the name, must hold at least ACPI_NAME_MAX
* bytes
* @return 0 if OK, -ENOENT if no name is available, other -ve value on
* other error
*/
int acpi_get_name(const struct udevice *dev, char *out_name);
/**
* acpi_copy_name() - Copy an ACPI name to an output buffer
*
* This convenience function can be used to return a literal string as a name
* in functions that implement the get_name() method.
*
* For example:
*
* static int mydev_get_name(const struct udevice *dev, char *out_name)
* {
* return acpi_copy_name(out_name, "WIBB");
* }
*
* @out_name: Place to put the name
* @name: Name to copy
* @return 0 (always)
*/
int acpi_copy_name(char *out_name, const char *name);
/**
* acpi_write_dev_tables() - Write ACPI tables required by devices
*
* This scans through all devices and tells them to write any tables they want
* to write.
*
* @return 0 if OK, -ve if any device returned an error
*/
int acpi_write_dev_tables(struct acpi_ctx *ctx);
/**
* acpi_fill_ssdt() - Generate ACPI tables for SSDT
*
* This is called to create the SSDT code for all devices.
*
* @ctx: ACPI context to use
* @return 0 if OK, -ve on error
*/
int acpi_fill_ssdt(struct acpi_ctx *ctx);
/**
* acpi_inject_dsdt() - Generate ACPI tables for DSDT
*
* This is called to create the DSDT code for all devices.
*
* @ctx: ACPI context to use
* @return 0 if OK, -ve on error
*/
int acpi_inject_dsdt(struct acpi_ctx *ctx);
/**
* acpi_setup_nhlt() - Set up audio information
*
* This is called to set up the nhlt information for all devices.
*
* @ctx: ACPI context to use
* @nhlt: Pointer to nhlt information to add to
* @return 0 if OK, -ve on error
*/
int acpi_setup_nhlt(struct acpi_ctx *ctx, struct nhlt *nhlt);
/**
* acpi_dump_items() - Dump out the collected ACPI items
*
* This lists the ACPI DSDT and SSDT items generated by the various U-Boot
* drivers.
*
* @option: Sets what should be dumpyed
*/
void acpi_dump_items(enum acpi_dump_option option);
/**
* acpi_get_path() - Get the full ACPI path for a device
*
* This checks for any override in the device tree and calls acpi_device_path()
* if not
*
* @dev: Device to check
* @out_path: Buffer to place the path in (should be ACPI_PATH_MAX long)
* @maxlen: Size of buffer (typically ACPI_PATH_MAX)
* @return 0 if OK, -ve on error
*/
int acpi_get_path(const struct udevice *dev, char *out_path, int maxlen);
/**
* acpi_reset_items() - Reset the list of ACPI items to empty
*
* This list keeps track of DSDT and SSDT items that are generated
* programmatically. The 'acpi items' command shows the list. Use this function
* to empty the list, before writing new items.
*/
void acpi_reset_items(void);
#endif /* __ACPI__ */
#endif
|