blob: 8ae61575dd3e9d5a4565ccf00d6a20f740fb4022 [file] [log] [blame]
Simon Glass7ca28502020-04-09 10:27:38 -06001// 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>
Simon Glassf7ae49f2020-05-10 11:40:05 -060013#include <log.h>
Simon Glass7ca28502020-04-09 10:27:38 -060014#include <dm/acpi.h>
Simon Glass93f7f822020-04-26 09:19:46 -060015#include <dm/device-internal.h>
Simon Glass7ca28502020-04-09 10:27:38 -060016#include <dm/root.h>
17
Simon Glass93f7f822020-04-26 09:19:46 -060018/* Type of method to call */
19enum method_t {
20 METHOD_WRITE_TABLES,
21};
22
23/* Prototype for all methods */
24typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx);
25
Simon Glass7ca28502020-04-09 10:27:38 -060026int acpi_copy_name(char *out_name, const char *name)
27{
28 strncpy(out_name, name, ACPI_NAME_LEN);
29 out_name[ACPI_NAME_LEN] = '\0';
30
31 return 0;
32}
33
34int acpi_get_name(const struct udevice *dev, char *out_name)
35{
36 struct acpi_ops *aops;
37
38 aops = device_get_acpi_ops(dev);
39 if (aops && aops->get_name)
40 return aops->get_name(dev, out_name);
41
42 return -ENOSYS;
43}
Simon Glass93f7f822020-04-26 09:19:46 -060044
45acpi_method acpi_get_method(struct udevice *dev, enum method_t method)
46{
47 struct acpi_ops *aops;
48
49 aops = device_get_acpi_ops(dev);
50 if (aops) {
51 switch (method) {
52 case METHOD_WRITE_TABLES:
53 return aops->write_tables;
54 }
55 }
56
57 return NULL;
58}
59
60int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent,
61 enum method_t method)
62{
63 struct udevice *dev;
64 acpi_method func;
65 int ret;
66
67 func = acpi_get_method(parent, method);
68 if (func) {
69 log_debug("\n");
70 log_debug("- %s %p\n", parent->name, func);
71 ret = device_ofdata_to_platdata(parent);
72 if (ret)
73 return log_msg_ret("ofdata", ret);
74 ret = func(parent, ctx);
75 if (ret)
76 return log_msg_ret("func", ret);
77 }
78 device_foreach_child(dev, parent) {
79 ret = acpi_recurse_method(ctx, dev, method);
80 if (ret)
81 return log_msg_ret("recurse", ret);
82 }
83
84 return 0;
85}
86
87int acpi_write_dev_tables(struct acpi_ctx *ctx)
88{
89 int ret;
90
91 log_debug("Writing device tables\n");
92 ret = acpi_recurse_method(ctx, dm_root(), METHOD_WRITE_TABLES);
93 log_debug("Writing finished, err=%d\n", ret);
94
95 return ret;
96}