Skip to content

Commit 2b9c698

Browse files
committed
ACPI / scan: Take the PRP0001 position in the list of IDs into account
If the special PRP0001 device ID is present in a device's _CID list, it should not prevent any ACPI/PNP IDs preceding it in the device's list of identifiers from being matched first. That is, only if none of the IDs preceding PRP0001 in the device's PNP/ACPI IDs list matches the IDs recognized by the driver, the driver's list of "compatible" IDs should be matched against the device's "compatible" property, if present. In addition to that, drivers can provide both acpi_match_table and of_match_table at the same time and the of_compatible matching should be used in that case too if PRP0001 is present in the device's list of identifiers. To make that happen, rework acpi_driver_match_device() to do the "compatible" property check in addition to matching the driver's list of ACPI IDs against the device's one. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
1 parent e1acdeb commit 2b9c698

File tree

1 file changed

+65
-50
lines changed

1 file changed

+65
-50
lines changed

drivers/acpi/scan.c

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,51 @@ static void acpi_device_remove_files(struct acpi_device *dev)
895895
ACPI Bus operations
896896
-------------------------------------------------------------------------- */
897897

898+
/**
899+
* acpi_of_match_device - Match device object using the "compatible" property.
900+
* @adev: ACPI device object to match.
901+
* @of_match_table: List of device IDs to match against.
902+
*
903+
* If @dev has an ACPI companion which has the special PRP0001 device ID in its
904+
* list of identifiers and a _DSD object with the "compatible" property, use
905+
* that property to match against the given list of identifiers.
906+
*/
907+
static bool acpi_of_match_device(struct acpi_device *adev,
908+
const struct of_device_id *of_match_table)
909+
{
910+
const union acpi_object *of_compatible, *obj;
911+
int i, nval;
912+
913+
if (!adev)
914+
return false;
915+
916+
of_compatible = adev->data.of_compatible;
917+
if (!of_match_table || !of_compatible)
918+
return false;
919+
920+
if (of_compatible->type == ACPI_TYPE_PACKAGE) {
921+
nval = of_compatible->package.count;
922+
obj = of_compatible->package.elements;
923+
} else { /* Must be ACPI_TYPE_STRING. */
924+
nval = 1;
925+
obj = of_compatible;
926+
}
927+
/* Now we can look for the driver DT compatible strings */
928+
for (i = 0; i < nval; i++, obj++) {
929+
const struct of_device_id *id;
930+
931+
for (id = of_match_table; id->compatible[0]; id++)
932+
if (!strcasecmp(obj->string.pointer, id->compatible))
933+
return true;
934+
}
935+
936+
return false;
937+
}
938+
898939
static const struct acpi_device_id *__acpi_match_device(
899-
struct acpi_device *device, const struct acpi_device_id *ids)
940+
struct acpi_device *device,
941+
const struct acpi_device_id *ids,
942+
const struct of_device_id *of_ids)
900943
{
901944
const struct acpi_device_id *id;
902945
struct acpi_hardware_id *hwid;
@@ -908,11 +951,24 @@ static const struct acpi_device_id *__acpi_match_device(
908951
if (!device || !device->status.present)
909952
return NULL;
910953

911-
for (id = ids; id->id[0]; id++)
912-
list_for_each_entry(hwid, &device->pnp.ids, list)
954+
list_for_each_entry(hwid, &device->pnp.ids, list) {
955+
/* First, check the ACPI/PNP IDs provided by the caller. */
956+
for (id = ids; id->id[0]; id++)
913957
if (!strcmp((char *) id->id, hwid->id))
914958
return id;
915959

960+
/*
961+
* Next, check the special "PRP0001" ID and try to match the
962+
* "compatible" property if found.
963+
*
964+
* The id returned by the below is not valid, but the only
965+
* caller passing non-NULL of_ids here is only interested in
966+
* whether or not the return value is NULL.
967+
*/
968+
if (!strcmp("PRP0001", hwid->id)
969+
&& acpi_of_match_device(device, of_ids))
970+
return id;
971+
}
916972
return NULL;
917973
}
918974

@@ -930,67 +986,26 @@ static const struct acpi_device_id *__acpi_match_device(
930986
const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
931987
const struct device *dev)
932988
{
933-
return __acpi_match_device(acpi_companion_match(dev), ids);
989+
return __acpi_match_device(acpi_companion_match(dev), ids, NULL);
934990
}
935991
EXPORT_SYMBOL_GPL(acpi_match_device);
936992

937993
int acpi_match_device_ids(struct acpi_device *device,
938994
const struct acpi_device_id *ids)
939995
{
940-
return __acpi_match_device(device, ids) ? 0 : -ENOENT;
996+
return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT;
941997
}
942998
EXPORT_SYMBOL(acpi_match_device_ids);
943999

944-
/**
945-
* acpi_of_match_device - Match device using the "compatible" property.
946-
* @dev: Device to match.
947-
* @of_match_table: List of device IDs to match against.
948-
*
949-
* If @dev has an ACPI companion which has the special PRP0001 device ID in its
950-
* list of identifiers and a _DSD object with the "compatible" property, use
951-
* that property to match against the given list of identifiers.
952-
*/
953-
static bool acpi_of_match_device(struct device *dev,
954-
const struct of_device_id *of_match_table)
955-
{
956-
const union acpi_object *of_compatible, *obj;
957-
struct acpi_device *adev;
958-
int i, nval;
959-
960-
adev = ACPI_COMPANION(dev);
961-
if (!adev)
962-
return false;
963-
964-
of_compatible = adev->data.of_compatible;
965-
if (!of_match_table || !of_compatible)
966-
return false;
967-
968-
if (of_compatible->type == ACPI_TYPE_PACKAGE) {
969-
nval = of_compatible->package.count;
970-
obj = of_compatible->package.elements;
971-
} else { /* Must be ACPI_TYPE_STRING. */
972-
nval = 1;
973-
obj = of_compatible;
974-
}
975-
/* Now we can look for the driver DT compatible strings */
976-
for (i = 0; i < nval; i++, obj++) {
977-
const struct of_device_id *id;
978-
979-
for (id = of_match_table; id->compatible[0]; id++)
980-
if (!strcasecmp(obj->string.pointer, id->compatible))
981-
return true;
982-
}
983-
984-
return false;
985-
}
986-
9871000
bool acpi_driver_match_device(struct device *dev,
9881001
const struct device_driver *drv)
9891002
{
9901003
if (!drv->acpi_match_table)
991-
return acpi_of_match_device(dev, drv->of_match_table);
1004+
return acpi_of_match_device(ACPI_COMPANION(dev),
1005+
drv->of_match_table);
9921006

993-
return !!acpi_match_device(drv->acpi_match_table, dev);
1007+
return !!__acpi_match_device(acpi_companion_match(dev),
1008+
drv->acpi_match_table, drv->of_match_table);
9941009
}
9951010
EXPORT_SYMBOL_GPL(acpi_driver_match_device);
9961011

0 commit comments

Comments
 (0)