diff options
author | Bartlomiej Grzesik <bag@semihalf.com> | 2021-07-30 08:57:06 +0000 |
---|---|---|
committer | Marcin Wojtas <mw@FreeBSD.org> | 2021-09-20 15:17:57 +0000 |
commit | 3f9a00e3b577dcca57e331842e0baf2dbdf9325f (patch) | |
tree | a98e04816c3daab6ff32ea9ad881bd85f0aa9010 /sys/dev/acpica | |
parent | b91fc6c43a81d3b760fb570c8439a922e536d7e6 (diff) | |
download | src-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.c | 37 |
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) { |