aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c129
1 files changed, 118 insertions, 11 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 0476e90b2091..9cb5cca3cfe3 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -124,17 +124,56 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
124 if (list_empty(&acpi_dev->pnp.ids)) 124 if (list_empty(&acpi_dev->pnp.ids))
125 return 0; 125 return 0;
126 126
127 len = snprintf(modalias, size, "acpi:"); 127 /*
128 size -= len; 128 * If the device has PRP0001 we expose DT compatible modalias
129 129 * instead in form of of:NnameTCcompatible.
130 list_for_each_entry(id, &acpi_dev->pnp.ids, list) { 130 */
131 count = snprintf(&modalias[len], size, "%s:", id->id); 131 if (acpi_dev->data.of_compatible) {
132 if (count < 0) 132 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
133 return -EINVAL; 133 const union acpi_object *of_compatible, *obj;
134 if (count >= size) 134 int i, nval;
135 return -ENOMEM; 135 char *c;
136 len += count; 136
137 size -= count; 137 acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
138 /* DT strings are all in lower case */
139 for (c = buf.pointer; *c != '\0'; c++)
140 *c = tolower(*c);
141
142 len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
143 ACPI_FREE(buf.pointer);
144
145 of_compatible = acpi_dev->data.of_compatible;
146 if (of_compatible->type == ACPI_TYPE_PACKAGE) {
147 nval = of_compatible->package.count;
148 obj = of_compatible->package.elements;
149 } else { /* Must be ACPI_TYPE_STRING. */
150 nval = 1;
151 obj = of_compatible;
152 }
153 for (i = 0; i < nval; i++, obj++) {
154 count = snprintf(&modalias[len], size, "C%s",
155 obj->string.pointer);
156 if (count < 0)
157 return -EINVAL;
158 if (count >= size)
159 return -ENOMEM;
160
161 len += count;
162 size -= count;
163 }
164 } else {
165 len = snprintf(modalias, size, "acpi:");
166 size -= len;
167
168 list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
169 count = snprintf(&modalias[len], size, "%s:", id->id);
170 if (count < 0)
171 return -EINVAL;
172 if (count >= size)
173 return -ENOMEM;
174 len += count;
175 size -= count;
176 }
138 } 177 }
139 178
140 modalias[len] = '\0'; 179 modalias[len] = '\0';
@@ -902,6 +941,51 @@ int acpi_match_device_ids(struct acpi_device *device,
902} 941}
903EXPORT_SYMBOL(acpi_match_device_ids); 942EXPORT_SYMBOL(acpi_match_device_ids);
904 943
944/* Performs match against special "PRP0001" shoehorn ACPI ID */
945static bool acpi_of_driver_match_device(struct device *dev,
946 const struct device_driver *drv)
947{
948 const union acpi_object *of_compatible, *obj;
949 struct acpi_device *adev;
950 int i, nval;
951
952 adev = ACPI_COMPANION(dev);
953 if (!adev)
954 return false;
955
956 of_compatible = adev->data.of_compatible;
957 if (!drv->of_match_table || !of_compatible)
958 return false;
959
960 if (of_compatible->type == ACPI_TYPE_PACKAGE) {
961 nval = of_compatible->package.count;
962 obj = of_compatible->package.elements;
963 } else { /* Must be ACPI_TYPE_STRING. */
964 nval = 1;
965 obj = of_compatible;
966 }
967 /* Now we can look for the driver DT compatible strings */
968 for (i = 0; i < nval; i++, obj++) {
969 const struct of_device_id *id;
970
971 for (id = drv->of_match_table; id->compatible[0]; id++)
972 if (!strcasecmp(obj->string.pointer, id->compatible))
973 return true;
974 }
975
976 return false;
977}
978
979bool acpi_driver_match_device(struct device *dev,
980 const struct device_driver *drv)
981{
982 if (!drv->acpi_match_table)
983 return acpi_of_driver_match_device(dev, drv);
984
985 return !!acpi_match_device(drv->acpi_match_table, dev);
986}
987EXPORT_SYMBOL_GPL(acpi_driver_match_device);
988
905static void acpi_free_power_resources_lists(struct acpi_device *device) 989static void acpi_free_power_resources_lists(struct acpi_device *device)
906{ 990{
907 int i; 991 int i;
@@ -922,6 +1006,7 @@ static void acpi_device_release(struct device *dev)
922{ 1006{
923 struct acpi_device *acpi_dev = to_acpi_device(dev); 1007 struct acpi_device *acpi_dev = to_acpi_device(dev);
924 1008
1009 acpi_free_properties(acpi_dev);
925 acpi_free_pnp_ids(&acpi_dev->pnp); 1010 acpi_free_pnp_ids(&acpi_dev->pnp);
926 acpi_free_power_resources_lists(acpi_dev); 1011 acpi_free_power_resources_lists(acpi_dev);
927 kfree(acpi_dev); 1012 kfree(acpi_dev);
@@ -1304,6 +1389,26 @@ int acpi_device_add(struct acpi_device *device,
1304 return result; 1389 return result;
1305} 1390}
1306 1391
1392struct acpi_device *acpi_get_next_child(struct device *dev,
1393 struct acpi_device *child)
1394{
1395 struct acpi_device *adev = ACPI_COMPANION(dev);
1396 struct list_head *head, *next;
1397
1398 if (!adev)
1399 return NULL;
1400
1401 head = &adev->children;
1402 if (list_empty(head))
1403 return NULL;
1404
1405 if (!child)
1406 return list_first_entry(head, struct acpi_device, node);
1407
1408 next = child->node.next;
1409 return next == head ? NULL : list_entry(next, struct acpi_device, node);
1410}
1411
1307/* -------------------------------------------------------------------------- 1412/* --------------------------------------------------------------------------
1308 Driver Management 1413 Driver Management
1309 -------------------------------------------------------------------------- */ 1414 -------------------------------------------------------------------------- */
@@ -1923,9 +2028,11 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
1923 device->device_type = type; 2028 device->device_type = type;
1924 device->handle = handle; 2029 device->handle = handle;
1925 device->parent = acpi_bus_get_parent(handle); 2030 device->parent = acpi_bus_get_parent(handle);
2031 device->fwnode.type = FWNODE_ACPI;
1926 acpi_set_device_status(device, sta); 2032 acpi_set_device_status(device, sta);
1927 acpi_device_get_busid(device); 2033 acpi_device_get_busid(device);
1928 acpi_set_pnp_ids(handle, &device->pnp, type); 2034 acpi_set_pnp_ids(handle, &device->pnp, type);
2035 acpi_init_properties(device);
1929 acpi_bus_get_flags(device); 2036 acpi_bus_get_flags(device);
1930 device->flags.match_driver = false; 2037 device->flags.match_driver = false;
1931 device->flags.initialized = true; 2038 device->flags.initialized = true;