]>
Commit | Line | Data |
---|---|---|
7ca2850c SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Core driver model support for ACPI table generation | |
4 | * | |
5 | * Copyright 2019 Google LLC | |
6 | * Written by Simon Glass <sjg@chromium.org> | |
7 | */ | |
8 | ||
9 | #define LOG_CATEOGRY LOGC_ACPI | |
10 | ||
11 | #include <common.h> | |
12 | #include <dm.h> | |
13 | #include <dm/acpi.h> | |
93f7f827 | 14 | #include <dm/device-internal.h> |
7ca2850c SG |
15 | #include <dm/root.h> |
16 | ||
93f7f827 SG |
17 | /* Type of method to call */ |
18 | enum method_t { | |
19 | METHOD_WRITE_TABLES, | |
20 | }; | |
21 | ||
22 | /* Prototype for all methods */ | |
23 | typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx); | |
24 | ||
7ca2850c SG |
25 | int acpi_copy_name(char *out_name, const char *name) |
26 | { | |
27 | strncpy(out_name, name, ACPI_NAME_LEN); | |
28 | out_name[ACPI_NAME_LEN] = '\0'; | |
29 | ||
30 | return 0; | |
31 | } | |
32 | ||
33 | int acpi_get_name(const struct udevice *dev, char *out_name) | |
34 | { | |
35 | struct acpi_ops *aops; | |
36 | ||
37 | aops = device_get_acpi_ops(dev); | |
38 | if (aops && aops->get_name) | |
39 | return aops->get_name(dev, out_name); | |
40 | ||
41 | return -ENOSYS; | |
42 | } | |
93f7f827 SG |
43 | |
44 | acpi_method acpi_get_method(struct udevice *dev, enum method_t method) | |
45 | { | |
46 | struct acpi_ops *aops; | |
47 | ||
48 | aops = device_get_acpi_ops(dev); | |
49 | if (aops) { | |
50 | switch (method) { | |
51 | case METHOD_WRITE_TABLES: | |
52 | return aops->write_tables; | |
53 | } | |
54 | } | |
55 | ||
56 | return NULL; | |
57 | } | |
58 | ||
59 | int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent, | |
60 | enum method_t method) | |
61 | { | |
62 | struct udevice *dev; | |
63 | acpi_method func; | |
64 | int ret; | |
65 | ||
66 | func = acpi_get_method(parent, method); | |
67 | if (func) { | |
68 | log_debug("\n"); | |
69 | log_debug("- %s %p\n", parent->name, func); | |
70 | ret = device_ofdata_to_platdata(parent); | |
71 | if (ret) | |
72 | return log_msg_ret("ofdata", ret); | |
73 | ret = func(parent, ctx); | |
74 | if (ret) | |
75 | return log_msg_ret("func", ret); | |
76 | } | |
77 | device_foreach_child(dev, parent) { | |
78 | ret = acpi_recurse_method(ctx, dev, method); | |
79 | if (ret) | |
80 | return log_msg_ret("recurse", ret); | |
81 | } | |
82 | ||
83 | return 0; | |
84 | } | |
85 | ||
86 | int acpi_write_dev_tables(struct acpi_ctx *ctx) | |
87 | { | |
88 | int ret; | |
89 | ||
90 | log_debug("Writing device tables\n"); | |
91 | ret = acpi_recurse_method(ctx, dm_root(), METHOD_WRITE_TABLES); | |
92 | log_debug("Writing finished, err=%d\n", ret); | |
93 | ||
94 | return ret; | |
95 | } |