1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*d83cc019SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*d83cc019SAndroid Build Coastguard Worker * SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker */
23*d83cc019SAndroid Build Coastguard Worker
24*d83cc019SAndroid Build Coastguard Worker #include <ctype.h>
25*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
26*d83cc019SAndroid Build Coastguard Worker #include <regex.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker
33*d83cc019SAndroid Build Coastguard Worker #include "intel_reg_spec.h"
34*d83cc019SAndroid Build Coastguard Worker
35*d83cc019SAndroid Build Coastguard Worker static const struct port_desc port_descs[] = {
36*d83cc019SAndroid Build Coastguard Worker {
37*d83cc019SAndroid Build Coastguard Worker .name = "mmio",
38*d83cc019SAndroid Build Coastguard Worker .port = PORT_MMIO,
39*d83cc019SAndroid Build Coastguard Worker .stride = 4,
40*d83cc019SAndroid Build Coastguard Worker },
41*d83cc019SAndroid Build Coastguard Worker {
42*d83cc019SAndroid Build Coastguard Worker .name = "portio-vga",
43*d83cc019SAndroid Build Coastguard Worker .port = PORT_PORTIO_VGA,
44*d83cc019SAndroid Build Coastguard Worker .stride = 1,
45*d83cc019SAndroid Build Coastguard Worker },
46*d83cc019SAndroid Build Coastguard Worker {
47*d83cc019SAndroid Build Coastguard Worker .name = "mmio-vga",
48*d83cc019SAndroid Build Coastguard Worker .port = PORT_MMIO_VGA,
49*d83cc019SAndroid Build Coastguard Worker .stride = 1,
50*d83cc019SAndroid Build Coastguard Worker },
51*d83cc019SAndroid Build Coastguard Worker {
52*d83cc019SAndroid Build Coastguard Worker .name = "bunit",
53*d83cc019SAndroid Build Coastguard Worker .port = PORT_BUNIT,
54*d83cc019SAndroid Build Coastguard Worker .stride = 1,
55*d83cc019SAndroid Build Coastguard Worker },
56*d83cc019SAndroid Build Coastguard Worker {
57*d83cc019SAndroid Build Coastguard Worker .name = "punit",
58*d83cc019SAndroid Build Coastguard Worker .port = PORT_PUNIT,
59*d83cc019SAndroid Build Coastguard Worker .stride = 1,
60*d83cc019SAndroid Build Coastguard Worker },
61*d83cc019SAndroid Build Coastguard Worker {
62*d83cc019SAndroid Build Coastguard Worker .name = "nc",
63*d83cc019SAndroid Build Coastguard Worker .port = PORT_NC,
64*d83cc019SAndroid Build Coastguard Worker .stride = 4,
65*d83cc019SAndroid Build Coastguard Worker },
66*d83cc019SAndroid Build Coastguard Worker {
67*d83cc019SAndroid Build Coastguard Worker .name = "dpio",
68*d83cc019SAndroid Build Coastguard Worker .port = PORT_DPIO,
69*d83cc019SAndroid Build Coastguard Worker .stride = 4,
70*d83cc019SAndroid Build Coastguard Worker },
71*d83cc019SAndroid Build Coastguard Worker {
72*d83cc019SAndroid Build Coastguard Worker .name = "gpio-nc",
73*d83cc019SAndroid Build Coastguard Worker .port = PORT_GPIO_NC,
74*d83cc019SAndroid Build Coastguard Worker .stride = 4,
75*d83cc019SAndroid Build Coastguard Worker },
76*d83cc019SAndroid Build Coastguard Worker {
77*d83cc019SAndroid Build Coastguard Worker .name = "gpio_nc",
78*d83cc019SAndroid Build Coastguard Worker .port = PORT_GPIO_NC,
79*d83cc019SAndroid Build Coastguard Worker .stride = 4,
80*d83cc019SAndroid Build Coastguard Worker },
81*d83cc019SAndroid Build Coastguard Worker {
82*d83cc019SAndroid Build Coastguard Worker .name = "cck",
83*d83cc019SAndroid Build Coastguard Worker .port = PORT_CCK,
84*d83cc019SAndroid Build Coastguard Worker .stride = 1,
85*d83cc019SAndroid Build Coastguard Worker },
86*d83cc019SAndroid Build Coastguard Worker {
87*d83cc019SAndroid Build Coastguard Worker .name = "ccu",
88*d83cc019SAndroid Build Coastguard Worker .port = PORT_CCU,
89*d83cc019SAndroid Build Coastguard Worker .stride = 4,
90*d83cc019SAndroid Build Coastguard Worker },
91*d83cc019SAndroid Build Coastguard Worker {
92*d83cc019SAndroid Build Coastguard Worker .name = "dpio2",
93*d83cc019SAndroid Build Coastguard Worker .port = PORT_DPIO2,
94*d83cc019SAndroid Build Coastguard Worker .stride = 4,
95*d83cc019SAndroid Build Coastguard Worker },
96*d83cc019SAndroid Build Coastguard Worker {
97*d83cc019SAndroid Build Coastguard Worker .name = "flisdsi",
98*d83cc019SAndroid Build Coastguard Worker .port = PORT_FLISDSI,
99*d83cc019SAndroid Build Coastguard Worker .stride = 1,
100*d83cc019SAndroid Build Coastguard Worker },
101*d83cc019SAndroid Build Coastguard Worker };
102*d83cc019SAndroid Build Coastguard Worker
103*d83cc019SAndroid Build Coastguard Worker /*
104*d83cc019SAndroid Build Coastguard Worker * Parse port desc of the form (PORTNAME|PORTNUM|MMIO-OFFSET) into reg. NULL or
105*d83cc019SAndroid Build Coastguard Worker * zero length s is regarded as MMIO.
106*d83cc019SAndroid Build Coastguard Worker */
parse_port_desc(struct reg * reg,const char * s)107*d83cc019SAndroid Build Coastguard Worker int parse_port_desc(struct reg *reg, const char *s)
108*d83cc019SAndroid Build Coastguard Worker {
109*d83cc019SAndroid Build Coastguard Worker enum port_addr port = PORT_NONE;
110*d83cc019SAndroid Build Coastguard Worker int i;
111*d83cc019SAndroid Build Coastguard Worker
112*d83cc019SAndroid Build Coastguard Worker if (s && *s) {
113*d83cc019SAndroid Build Coastguard Worker /* See if port is specified by number. */
114*d83cc019SAndroid Build Coastguard Worker char *endp;
115*d83cc019SAndroid Build Coastguard Worker unsigned long n = strtoul(s, &endp, 16);
116*d83cc019SAndroid Build Coastguard Worker if (endp > s && *endp == 0) {
117*d83cc019SAndroid Build Coastguard Worker if (n > PORT_MAX) {
118*d83cc019SAndroid Build Coastguard Worker /* Not a sideband port, assume MMIO offset. */
119*d83cc019SAndroid Build Coastguard Worker port = PORT_MMIO;
120*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = n;
121*d83cc019SAndroid Build Coastguard Worker } else {
122*d83cc019SAndroid Build Coastguard Worker port = n;
123*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = 0;
124*d83cc019SAndroid Build Coastguard Worker }
125*d83cc019SAndroid Build Coastguard Worker } else {
126*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = 0;
127*d83cc019SAndroid Build Coastguard Worker }
128*d83cc019SAndroid Build Coastguard Worker } else {
129*d83cc019SAndroid Build Coastguard Worker /* No port, default to searching for MMIO. */
130*d83cc019SAndroid Build Coastguard Worker port = PORT_MMIO;
131*d83cc019SAndroid Build Coastguard Worker reg->mmio_offset = 0;
132*d83cc019SAndroid Build Coastguard Worker }
133*d83cc019SAndroid Build Coastguard Worker
134*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(port_descs); i++) {
135*d83cc019SAndroid Build Coastguard Worker if ((port != PORT_NONE && port_descs[i].port == port) ||
136*d83cc019SAndroid Build Coastguard Worker (s && strcasecmp(s, port_descs[i].name) == 0)) {
137*d83cc019SAndroid Build Coastguard Worker reg->port_desc = port_descs[i];
138*d83cc019SAndroid Build Coastguard Worker return 0;
139*d83cc019SAndroid Build Coastguard Worker }
140*d83cc019SAndroid Build Coastguard Worker }
141*d83cc019SAndroid Build Coastguard Worker
142*d83cc019SAndroid Build Coastguard Worker return -1;
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker
skip_space(const char * line)145*d83cc019SAndroid Build Coastguard Worker static const char *skip_space(const char *line)
146*d83cc019SAndroid Build Coastguard Worker {
147*d83cc019SAndroid Build Coastguard Worker while (*line && isspace(*line))
148*d83cc019SAndroid Build Coastguard Worker line++;
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker return line;
151*d83cc019SAndroid Build Coastguard Worker }
152*d83cc019SAndroid Build Coastguard Worker
ignore_line(const char * line)153*d83cc019SAndroid Build Coastguard Worker static bool ignore_line(const char *line)
154*d83cc019SAndroid Build Coastguard Worker {
155*d83cc019SAndroid Build Coastguard Worker line = skip_space(line);
156*d83cc019SAndroid Build Coastguard Worker
157*d83cc019SAndroid Build Coastguard Worker switch (*line) {
158*d83cc019SAndroid Build Coastguard Worker case '\0':
159*d83cc019SAndroid Build Coastguard Worker case '#':
160*d83cc019SAndroid Build Coastguard Worker case ';':
161*d83cc019SAndroid Build Coastguard Worker return true;
162*d83cc019SAndroid Build Coastguard Worker case '/':
163*d83cc019SAndroid Build Coastguard Worker return *(line + 1) == '/';
164*d83cc019SAndroid Build Coastguard Worker }
165*d83cc019SAndroid Build Coastguard Worker
166*d83cc019SAndroid Build Coastguard Worker return false;
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker
include_file(const char * line,const char * source)169*d83cc019SAndroid Build Coastguard Worker static char *include_file(const char *line, const char *source)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker char *filename, *p;
172*d83cc019SAndroid Build Coastguard Worker
173*d83cc019SAndroid Build Coastguard Worker line = skip_space(line);
174*d83cc019SAndroid Build Coastguard Worker if (*line == '(')
175*d83cc019SAndroid Build Coastguard Worker return NULL;
176*d83cc019SAndroid Build Coastguard Worker
177*d83cc019SAndroid Build Coastguard Worker /* this'll be plenty */
178*d83cc019SAndroid Build Coastguard Worker filename = malloc(strlen(source) + strlen(line) + 1);
179*d83cc019SAndroid Build Coastguard Worker if (!filename)
180*d83cc019SAndroid Build Coastguard Worker return NULL;
181*d83cc019SAndroid Build Coastguard Worker
182*d83cc019SAndroid Build Coastguard Worker p = strrchr(source, '/');
183*d83cc019SAndroid Build Coastguard Worker if (p && *line != '/') {
184*d83cc019SAndroid Build Coastguard Worker int len = p - source + 1;
185*d83cc019SAndroid Build Coastguard Worker
186*d83cc019SAndroid Build Coastguard Worker memcpy(filename, source, len);
187*d83cc019SAndroid Build Coastguard Worker strcpy(filename + len, line);
188*d83cc019SAndroid Build Coastguard Worker } else {
189*d83cc019SAndroid Build Coastguard Worker strcpy(filename, line);
190*d83cc019SAndroid Build Coastguard Worker }
191*d83cc019SAndroid Build Coastguard Worker
192*d83cc019SAndroid Build Coastguard Worker p = strchr(filename, '\n');
193*d83cc019SAndroid Build Coastguard Worker if (p)
194*d83cc019SAndroid Build Coastguard Worker *p = '\0';
195*d83cc019SAndroid Build Coastguard Worker
196*d83cc019SAndroid Build Coastguard Worker return filename;
197*d83cc019SAndroid Build Coastguard Worker }
198*d83cc019SAndroid Build Coastguard Worker
199*d83cc019SAndroid Build Coastguard Worker #define SPC "[[:space:]]*"
200*d83cc019SAndroid Build Coastguard Worker #define SEP SPC "," SPC
201*d83cc019SAndroid Build Coastguard Worker #define BEG "^" SPC "\\(" SPC
202*d83cc019SAndroid Build Coastguard Worker #define END SPC "\\)" SPC "$"
203*d83cc019SAndroid Build Coastguard Worker #define VALUE "([[:print:]]*)"
204*d83cc019SAndroid Build Coastguard Worker #define QVALUE "'" VALUE "'"
205*d83cc019SAndroid Build Coastguard Worker #define REGEXP BEG QVALUE SEP QVALUE SEP QVALUE END
206*d83cc019SAndroid Build Coastguard Worker
parse_line(struct reg * reg,const char * line)207*d83cc019SAndroid Build Coastguard Worker static int parse_line(struct reg *reg, const char *line)
208*d83cc019SAndroid Build Coastguard Worker {
209*d83cc019SAndroid Build Coastguard Worker static regex_t regex;
210*d83cc019SAndroid Build Coastguard Worker static bool initialized = false;
211*d83cc019SAndroid Build Coastguard Worker regmatch_t match[4];
212*d83cc019SAndroid Build Coastguard Worker int i, ret;
213*d83cc019SAndroid Build Coastguard Worker
214*d83cc019SAndroid Build Coastguard Worker if (!initialized) {
215*d83cc019SAndroid Build Coastguard Worker if (regcomp (®ex, REGEXP, REG_EXTENDED)) {
216*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "regcomp %s\n", REGEXP);
217*d83cc019SAndroid Build Coastguard Worker return -1;
218*d83cc019SAndroid Build Coastguard Worker }
219*d83cc019SAndroid Build Coastguard Worker initialized = true;
220*d83cc019SAndroid Build Coastguard Worker }
221*d83cc019SAndroid Build Coastguard Worker
222*d83cc019SAndroid Build Coastguard Worker ret = regexec(®ex, line, ARRAY_SIZE(match), match, 0);
223*d83cc019SAndroid Build Coastguard Worker if (ret)
224*d83cc019SAndroid Build Coastguard Worker ret = -1;
225*d83cc019SAndroid Build Coastguard Worker
226*d83cc019SAndroid Build Coastguard Worker for (i = 1; i < ARRAY_SIZE(match) && ret == 0; i++) {
227*d83cc019SAndroid Build Coastguard Worker char *p, *e;
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker p = strndup(line + match[i].rm_so,
230*d83cc019SAndroid Build Coastguard Worker match[i].rm_eo - match[i].rm_so);
231*d83cc019SAndroid Build Coastguard Worker
232*d83cc019SAndroid Build Coastguard Worker if (i == 1) {
233*d83cc019SAndroid Build Coastguard Worker reg->name = p;
234*d83cc019SAndroid Build Coastguard Worker } else if (i == 2) {
235*d83cc019SAndroid Build Coastguard Worker reg->addr = strtoul(p, &e, 16);
236*d83cc019SAndroid Build Coastguard Worker free(p);
237*d83cc019SAndroid Build Coastguard Worker if (*e)
238*d83cc019SAndroid Build Coastguard Worker ret = -1;
239*d83cc019SAndroid Build Coastguard Worker } else if (i == 3) {
240*d83cc019SAndroid Build Coastguard Worker ret = parse_port_desc(reg, p);
241*d83cc019SAndroid Build Coastguard Worker free(p);
242*d83cc019SAndroid Build Coastguard Worker }
243*d83cc019SAndroid Build Coastguard Worker }
244*d83cc019SAndroid Build Coastguard Worker
245*d83cc019SAndroid Build Coastguard Worker if (ret)
246*d83cc019SAndroid Build Coastguard Worker free(reg->name);
247*d83cc019SAndroid Build Coastguard Worker
248*d83cc019SAndroid Build Coastguard Worker return ret;
249*d83cc019SAndroid Build Coastguard Worker }
250*d83cc019SAndroid Build Coastguard Worker
parse_file(struct reg ** regs,size_t * nregs,ssize_t index,const char * filename)251*d83cc019SAndroid Build Coastguard Worker static ssize_t parse_file(struct reg **regs, size_t *nregs,
252*d83cc019SAndroid Build Coastguard Worker ssize_t index, const char *filename)
253*d83cc019SAndroid Build Coastguard Worker {
254*d83cc019SAndroid Build Coastguard Worker FILE *file;
255*d83cc019SAndroid Build Coastguard Worker char *line = NULL, *include;
256*d83cc019SAndroid Build Coastguard Worker size_t linesize = 0;
257*d83cc019SAndroid Build Coastguard Worker int lineno = 0, r;
258*d83cc019SAndroid Build Coastguard Worker ssize_t ret = -1;
259*d83cc019SAndroid Build Coastguard Worker
260*d83cc019SAndroid Build Coastguard Worker file = fopen(filename, "r");
261*d83cc019SAndroid Build Coastguard Worker if (!file) {
262*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error: fopen '%s': %s\n",
263*d83cc019SAndroid Build Coastguard Worker filename, strerror(errno));
264*d83cc019SAndroid Build Coastguard Worker return -1;
265*d83cc019SAndroid Build Coastguard Worker }
266*d83cc019SAndroid Build Coastguard Worker
267*d83cc019SAndroid Build Coastguard Worker while (getline(&line, &linesize, file) != -1) {
268*d83cc019SAndroid Build Coastguard Worker struct reg reg = {};
269*d83cc019SAndroid Build Coastguard Worker
270*d83cc019SAndroid Build Coastguard Worker lineno++;
271*d83cc019SAndroid Build Coastguard Worker
272*d83cc019SAndroid Build Coastguard Worker if (ignore_line(line))
273*d83cc019SAndroid Build Coastguard Worker continue;
274*d83cc019SAndroid Build Coastguard Worker
275*d83cc019SAndroid Build Coastguard Worker include = include_file(line, filename);
276*d83cc019SAndroid Build Coastguard Worker if (include) {
277*d83cc019SAndroid Build Coastguard Worker index = parse_file(regs, nregs, index, include);
278*d83cc019SAndroid Build Coastguard Worker free(include);
279*d83cc019SAndroid Build Coastguard Worker if (index < 0) {
280*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error: %s:%d: %s",
281*d83cc019SAndroid Build Coastguard Worker filename, lineno, line);
282*d83cc019SAndroid Build Coastguard Worker goto out;
283*d83cc019SAndroid Build Coastguard Worker }
284*d83cc019SAndroid Build Coastguard Worker continue;
285*d83cc019SAndroid Build Coastguard Worker }
286*d83cc019SAndroid Build Coastguard Worker
287*d83cc019SAndroid Build Coastguard Worker r = parse_line(®, line);
288*d83cc019SAndroid Build Coastguard Worker if (r < 0) {
289*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error: %s:%d: %s",
290*d83cc019SAndroid Build Coastguard Worker filename, lineno, line);
291*d83cc019SAndroid Build Coastguard Worker goto out;
292*d83cc019SAndroid Build Coastguard Worker } else if (r) {
293*d83cc019SAndroid Build Coastguard Worker continue;
294*d83cc019SAndroid Build Coastguard Worker }
295*d83cc019SAndroid Build Coastguard Worker
296*d83cc019SAndroid Build Coastguard Worker if (!*regs || index >= *nregs) {
297*d83cc019SAndroid Build Coastguard Worker if (!*regs)
298*d83cc019SAndroid Build Coastguard Worker *nregs = 64;
299*d83cc019SAndroid Build Coastguard Worker else
300*d83cc019SAndroid Build Coastguard Worker *nregs *= 2;
301*d83cc019SAndroid Build Coastguard Worker
302*d83cc019SAndroid Build Coastguard Worker *regs = recalloc(*regs, *nregs, sizeof(**regs));
303*d83cc019SAndroid Build Coastguard Worker if (!*regs) {
304*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Error: %s\n", strerror(ENOMEM));
305*d83cc019SAndroid Build Coastguard Worker goto out;
306*d83cc019SAndroid Build Coastguard Worker }
307*d83cc019SAndroid Build Coastguard Worker }
308*d83cc019SAndroid Build Coastguard Worker
309*d83cc019SAndroid Build Coastguard Worker (*regs)[index++] = reg;
310*d83cc019SAndroid Build Coastguard Worker }
311*d83cc019SAndroid Build Coastguard Worker
312*d83cc019SAndroid Build Coastguard Worker ret = index;
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker out:
315*d83cc019SAndroid Build Coastguard Worker free(line);
316*d83cc019SAndroid Build Coastguard Worker fclose(file);
317*d83cc019SAndroid Build Coastguard Worker
318*d83cc019SAndroid Build Coastguard Worker return ret;
319*d83cc019SAndroid Build Coastguard Worker }
320*d83cc019SAndroid Build Coastguard Worker
321*d83cc019SAndroid Build Coastguard Worker /*
322*d83cc019SAndroid Build Coastguard Worker * Get register definitions from file.
323*d83cc019SAndroid Build Coastguard Worker */
intel_reg_spec_file(struct reg ** regs,const char * file)324*d83cc019SAndroid Build Coastguard Worker ssize_t intel_reg_spec_file(struct reg **regs, const char *file)
325*d83cc019SAndroid Build Coastguard Worker {
326*d83cc019SAndroid Build Coastguard Worker size_t nregs = 0;
327*d83cc019SAndroid Build Coastguard Worker *regs = NULL;
328*d83cc019SAndroid Build Coastguard Worker
329*d83cc019SAndroid Build Coastguard Worker return parse_file(regs, &nregs, 0, file);
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker
332*d83cc019SAndroid Build Coastguard Worker /*
333*d83cc019SAndroid Build Coastguard Worker * Free the memory allocated for register definitions.
334*d83cc019SAndroid Build Coastguard Worker */
intel_reg_spec_free(struct reg * regs,size_t n)335*d83cc019SAndroid Build Coastguard Worker void intel_reg_spec_free(struct reg *regs, size_t n)
336*d83cc019SAndroid Build Coastguard Worker {
337*d83cc019SAndroid Build Coastguard Worker size_t i;
338*d83cc019SAndroid Build Coastguard Worker
339*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
340*d83cc019SAndroid Build Coastguard Worker free(regs[i].name);
341*d83cc019SAndroid Build Coastguard Worker }
342*d83cc019SAndroid Build Coastguard Worker free(regs);
343*d83cc019SAndroid Build Coastguard Worker }
344*d83cc019SAndroid Build Coastguard Worker
intel_reg_spec_print_ports(void)345*d83cc019SAndroid Build Coastguard Worker void intel_reg_spec_print_ports(void)
346*d83cc019SAndroid Build Coastguard Worker {
347*d83cc019SAndroid Build Coastguard Worker int i;
348*d83cc019SAndroid Build Coastguard Worker
349*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(port_descs); i++)
350*d83cc019SAndroid Build Coastguard Worker printf("%s%s", i == 0 ? "" : ", ", port_descs[i].name);
351*d83cc019SAndroid Build Coastguard Worker }
352