blob: e09905cf2a066bcc0d49868b9748b6c664d8246e [file] [log] [blame]
Simon Glass9fb9e9b2020-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>
13#include <dm/acpi.h>
Simon Glass17968c32020-04-26 09:19:46 -060014#include <dm/device-internal.h>
Simon Glass9fb9e9b2020-04-09 10:27:38 -060015#include <dm/root.h>
16
Simon Glass17968c32020-04-26 09:19:46 -060017/* Type of method to call */
18enum method_t {
19 METHOD_WRITE_TABLES,
20};
21
22/* Prototype for all methods */
23typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx);
24
Simon Glass9fb9e9b2020-04-09 10:27:38 -060025int 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
33int 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}
Simon Glass17968c32020-04-26 09:19:46 -060043
44acpi_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
59int 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
86int 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}