diff --git a/sys/dev/acpi/acpi_util.c b/sys/dev/acpi/acpi_util.c index 3e81c7243d7a..0ce58a997fdc 100644 --- a/sys/dev/acpi/acpi_util.c +++ b/sys/dev/acpi/acpi_util.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_util.c,v 1.27 2021/12/20 11:17:40 skrll Exp $ */ +/* $NetBSD: acpi_util.c,v 1.28 2021/12/26 14:34:39 jmcneill Exp $ */ /*- * Copyright (c) 2003, 2007, 2021 The NetBSD Foundation, Inc. @@ -65,7 +65,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.27 2021/12/20 11:17:40 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_util.c,v 1.28 2021/12/26 14:34:39 jmcneill Exp $"); #include #include @@ -89,6 +89,11 @@ static const char * const acpicpu_ids[] = { NULL }; +static const struct device_compatible_entry dtlink_compat_data[] = { + { .compat = "PRP0001" }, + DEVICE_COMPAT_EOL +}; + /* * ACPI device handle support. */ @@ -445,6 +450,9 @@ acpi_compatible_match(const struct acpi_attach_args * const aa, { const char *strings[ACPI_COMPATSTR_MAX * sizeof(const char *)]; const char **cpp; + bool dtlink = false; + ACPI_STATUS ret; + int rv; if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) { return 0; @@ -459,23 +467,47 @@ acpi_compatible_match(const struct acpi_attach_args * const aa, if (device_compatible_pmatch(strings, 1, dce) != 0) { return ACPI_MATCHSCORE_HID; } + + if (device_compatible_pmatch(strings, 1, + dtlink_compat_data) != 0) { + dtlink = true; + } } if ((ad->Valid & ACPI_VALID_CID) != 0) { cpp = acpi_compatible_alloc_strarray(ad->CompatibleIdList.Ids, ad->CompatibleIdList.Count, strings); - int rv; rv = device_compatible_pmatch(cpp, ad->CompatibleIdList.Count, dce); + if (!dtlink && + device_compatible_pmatch(cpp, ad->CompatibleIdList.Count, + dtlink_compat_data) != 0) { + dtlink = true; + } acpi_compatible_free_strarray(cpp, ad->CompatibleIdList.Count, strings); if (rv) { rv = (rv - 1) + ACPI_MATCHSCORE_CID; - if (rv > ACPI_MATCHSCORE_CID_MAX) { - rv = ACPI_MATCHSCORE_CID_MAX; - } - return rv; + return imin(rv, ACPI_MATCHSCORE_CID_MAX); + } + } + + if (dtlink) { + char *compatible; + + ret = acpi_dsd_string(aa->aa_node->ad_handle, + "compatible", &compatible); + if (ACPI_FAILURE(ret)) { + return 0; + } + + strings[0] = compatible; + rv = device_compatible_pmatch(strings, 1, dce); + kmem_strfree(compatible); + if (rv) { + rv = (rv - 1) + ACPI_MATCHSCORE_CID; + return imin(rv, ACPI_MATCHSCORE_CID_MAX); } } diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index 6c840fb2087e..9dafef7f7ac5 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: acpivar.h,v 1.88 2021/12/20 11:17:40 skrll Exp $ */ +/* $NetBSD: acpivar.h,v 1.89 2021/12/26 14:34:39 jmcneill Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -198,7 +198,9 @@ struct acpi_attach_args { /* ACPI driver matching scores. */ #define ACPI_MATCHSCORE_HID 100 /* matched _HID */ #define ACPI_MATCHSCORE_CID_MAX 49 -#define ACPI_MATCHSCORE_CID 10 /* matched _CID */ +#define ACPI_MATCHSCORE_CID 10 /* matched _CID or _DSD + * "compatible" + */ #define ACPI_MATCHSCORE_CLS 1 /* matched _CLS */ /*