aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/scan.c115
1 files changed, 65 insertions, 50 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b4d5549265ed..8f3adf924e83 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -895,8 +895,51 @@ static void acpi_device_remove_files(struct acpi_device *dev)
895 ACPI Bus operations 895 ACPI Bus operations
896 -------------------------------------------------------------------------- */ 896 -------------------------------------------------------------------------- */
897 897
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 */
907static 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
898static const struct acpi_device_id *__acpi_match_device( 939static 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)
900{ 943{
901 const struct acpi_device_id *id; 944 const struct acpi_device_id *id;
902 struct acpi_hardware_id *hwid; 945 struct acpi_hardware_id *hwid;
@@ -908,11 +951,24 @@ static const struct acpi_device_id *__acpi_match_device(
908 if (!device || !device->status.present) 951 if (!device || !device->status.present)
909 return NULL; 952 return NULL;
910 953
911 for (id = ids; id->id[0]; id++) 954 list_for_each_entry(hwid, &device->pnp.ids, list) {
912 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++)
913 if (!strcmp((char *) id->id, hwid->id)) 957 if (!strcmp((char *) id->id, hwid->id))
914 return id; 958 return id;
915 959
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 }
916 return NULL; 972 return NULL;
917} 973}
918 974
@@ -930,67 +986,26 @@ static const struct acpi_device_id *__acpi_match_device(
930const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, 986const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
931 const struct device *dev) 987 const struct device *dev)
932{ 988{
933 return __acpi_match_device(acpi_companion_match(dev), ids); 989 return __acpi_match_device(acpi_companion_match(dev), ids, NULL);
934} 990}
935EXPORT_SYMBOL_GPL(acpi_match_device); 991EXPORT_SYMBOL_GPL(acpi_match_device);
936 992
937int acpi_match_device_ids(struct acpi_device *device, 993int acpi_match_device_ids(struct acpi_device *device,
938 const struct acpi_device_id *ids) 994 const struct acpi_device_id *ids)
939{ 995{
940 return __acpi_match_device(device, ids) ? 0 : -ENOENT; 996 return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT;
941} 997}
942EXPORT_SYMBOL(acpi_match_device_ids); 998EXPORT_SYMBOL(acpi_match_device_ids);
943 999
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 */
953static 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
987bool acpi_driver_match_device(struct device *dev, 1000bool acpi_driver_match_device(struct device *dev,
988 const struct device_driver *drv) 1001 const struct device_driver *drv)
989{ 1002{
990 if (!drv->acpi_match_table) 1003 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);
992 1006
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);
994} 1009}
995EXPORT_SYMBOL_GPL(acpi_driver_match_device); 1010EXPORT_SYMBOL_GPL(acpi_driver_match_device);
996 1011