aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authorBartlomiej Grzesik <bag@semihalf.com>2021-07-30 08:57:06 +0000
committerMarcin Wojtas <mw@FreeBSD.org>2021-09-20 15:17:57 +0000
commit3f9a00e3b577dcca57e331842e0baf2dbdf9325f (patch)
treea98e04816c3daab6ff32ea9ad881bd85f0aa9010 /sys/dev/acpica
parentb91fc6c43a81d3b760fb570c8439a922e536d7e6 (diff)
downloadsrc-3f9a00e3b577dcca57e331842e0baf2dbdf9325f.tar.gz
src-3f9a00e3b577dcca57e331842e0baf2dbdf9325f.zip
device: add device_get_property and device_has_property
Generialize bus specific property accessors. Those functions allow driver code to access device specific information. Currently there is only support for FDT and ACPI buses. Reviewed by: manu, mw Sponsored by: Semihalf Differential revision: https://reviews.freebsd.org/D31597
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/acpi.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 40b928f9cdd6..5d2b895bbe88 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -144,6 +144,8 @@ static void acpi_delete_resource(device_t bus, device_t child, int type,
int rid);
static uint32_t acpi_isa_get_logicalid(device_t dev);
static int acpi_isa_get_compatid(device_t dev, uint32_t *cids, int count);
+static ssize_t acpi_bus_get_prop(device_t bus, device_t child, const char *propname,
+ void *propvalue, size_t size);
static int acpi_device_id_probe(device_t bus, device_t dev, char **ids, char **match);
static ACPI_STATUS acpi_device_eval_obj(device_t bus, device_t dev,
ACPI_STRING pathname, ACPI_OBJECT_LIST *parameters,
@@ -223,6 +225,7 @@ static device_method_t acpi_methods[] = {
DEVMETHOD(bus_hint_device_unit, acpi_hint_device_unit),
DEVMETHOD(bus_get_cpus, acpi_get_cpus),
DEVMETHOD(bus_get_domain, acpi_get_domain),
+ DEVMETHOD(bus_get_property, acpi_bus_get_prop),
/* ACPI bus */
DEVMETHOD(acpi_id_probe, acpi_device_id_probe),
@@ -1817,6 +1820,40 @@ acpi_find_dsd(device_t bus, device_t dev)
return (AE_NOT_FOUND);
}
+static ssize_t
+acpi_bus_get_prop(device_t bus, device_t child, const char *propname,
+ void *propvalue, size_t size)
+{
+ ACPI_STATUS status;
+ const ACPI_OBJECT *obj;
+
+ status = acpi_device_get_prop(bus, child, __DECONST(char *, propname),
+ &obj);
+ if (ACPI_FAILURE(status))
+ return (-1);
+
+ switch (obj->Type) {
+ case ACPI_TYPE_INTEGER:
+ if (propvalue != NULL && size >= sizeof(uint64_t))
+ *((uint64_t *) propvalue) = obj->Integer.Value;
+ return (sizeof(uint64_t));
+
+ case ACPI_TYPE_STRING:
+ if (propvalue != NULL && size > 0)
+ memcpy(propvalue, obj->String.Pointer,
+ MIN(size, obj->String.Length));
+ return (obj->String.Length);
+
+ case ACPI_TYPE_BUFFER:
+ if (propvalue != NULL && size > 0)
+ memcpy(propvalue, obj->Buffer.Pointer,
+ MIN(size, obj->Buffer.Length));
+ return (obj->Buffer.Length);
+ }
+
+ return (-1);
+}
+
int
acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate)
{