aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-10 10:07:51 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-10 10:07:51 -0400
commit2b9c698efa58bf7d9a0d3d3b28115cf9e55ca818 (patch)
tree79071b3738d15a72e3db576561be744bebbf1e19
parente1acdeb0e7707f4220aa14ad6739102ba26e07c0 (diff)
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>
-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