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.c394
1 files changed, 236 insertions, 158 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index bbca7830e18a..69bc0d888c01 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -114,7 +114,12 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
114 return 0; 114 return 0;
115} 115}
116 116
117/* 117/**
118 * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent
119 * @acpi_dev: ACPI device object.
120 * @modalias: Buffer to print into.
121 * @size: Size of the buffer.
122 *
118 * Creates hid/cid(s) string needed for modalias and uevent 123 * Creates hid/cid(s) string needed for modalias and uevent
119 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: 124 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
120 * char *modalias: "acpi:IBM0001:ACPI0001" 125 * char *modalias: "acpi:IBM0001:ACPI0001"
@@ -122,68 +127,98 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
122 * -EINVAL: output error 127 * -EINVAL: output error
123 * -ENOMEM: output is truncated 128 * -ENOMEM: output is truncated
124*/ 129*/
125static int create_modalias(struct acpi_device *acpi_dev, char *modalias, 130static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
126 int size) 131 int size)
127{ 132{
128 int len; 133 int len;
129 int count; 134 int count;
130 struct acpi_hardware_id *id; 135 struct acpi_hardware_id *id;
131 136
132 if (list_empty(&acpi_dev->pnp.ids))
133 return 0;
134
135 /* 137 /*
136 * If the device has PRP0001 we expose DT compatible modalias 138 * Since we skip PRP0001 from the modalias below, 0 should be returned
137 * instead in form of of:NnameTCcompatible. 139 * if PRP0001 is the only ACPI/PNP ID in the device's list.
138 */ 140 */
139 if (acpi_dev->data.of_compatible) { 141 count = 0;
140 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 142 list_for_each_entry(id, &acpi_dev->pnp.ids, list)
141 const union acpi_object *of_compatible, *obj; 143 if (strcmp(id->id, "PRP0001"))
142 int i, nval; 144 count++;
143 char *c;
144
145 acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
146 /* DT strings are all in lower case */
147 for (c = buf.pointer; *c != '\0'; c++)
148 *c = tolower(*c);
149
150 len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
151 ACPI_FREE(buf.pointer);
152
153 of_compatible = acpi_dev->data.of_compatible;
154 if (of_compatible->type == ACPI_TYPE_PACKAGE) {
155 nval = of_compatible->package.count;
156 obj = of_compatible->package.elements;
157 } else { /* Must be ACPI_TYPE_STRING. */
158 nval = 1;
159 obj = of_compatible;
160 }
161 for (i = 0; i < nval; i++, obj++) {
162 count = snprintf(&modalias[len], size, "C%s",
163 obj->string.pointer);
164 if (count < 0)
165 return -EINVAL;
166 if (count >= size)
167 return -ENOMEM;
168
169 len += count;
170 size -= count;
171 }
172 } else {
173 len = snprintf(modalias, size, "acpi:");
174 size -= len;
175 145
176 list_for_each_entry(id, &acpi_dev->pnp.ids, list) { 146 if (!count)
177 count = snprintf(&modalias[len], size, "%s:", id->id); 147 return 0;
178 if (count < 0) 148
179 return -EINVAL; 149 len = snprintf(modalias, size, "acpi:");
180 if (count >= size) 150 if (len <= 0)
181 return -ENOMEM; 151 return len;
182 len += count; 152
183 size -= count; 153 size -= len;
184 } 154
155 list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
156 if (!strcmp(id->id, "PRP0001"))
157 continue;
158
159 count = snprintf(&modalias[len], size, "%s:", id->id);
160 if (count < 0)
161 return -EINVAL;
162
163 if (count >= size)
164 return -ENOMEM;
165
166 len += count;
167 size -= count;
168 }
169 modalias[len] = '\0';
170 return len;
171}
172
173/**
174 * create_of_modalias - Creates DT compatible string for modalias and uevent
175 * @acpi_dev: ACPI device object.
176 * @modalias: Buffer to print into.
177 * @size: Size of the buffer.
178 *
179 * Expose DT compatible modalias as of:NnameTCcompatible. This function should
180 * only be called for devices having PRP0001 in their list of ACPI/PNP IDs.
181 */
182static int create_of_modalias(struct acpi_device *acpi_dev, char *modalias,
183 int size)
184{
185 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
186 const union acpi_object *of_compatible, *obj;
187 int len, count;
188 int i, nval;
189 char *c;
190
191 acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
192 /* DT strings are all in lower case */
193 for (c = buf.pointer; *c != '\0'; c++)
194 *c = tolower(*c);
195
196 len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
197 ACPI_FREE(buf.pointer);
198
199 if (len <= 0)
200 return len;
201
202 of_compatible = acpi_dev->data.of_compatible;
203 if (of_compatible->type == ACPI_TYPE_PACKAGE) {
204 nval = of_compatible->package.count;
205 obj = of_compatible->package.elements;
206 } else { /* Must be ACPI_TYPE_STRING. */
207 nval = 1;
208 obj = of_compatible;
185 } 209 }
210 for (i = 0; i < nval; i++, obj++) {
211 count = snprintf(&modalias[len], size, "C%s",
212 obj->string.pointer);
213 if (count < 0)
214 return -EINVAL;
186 215
216 if (count >= size)
217 return -ENOMEM;
218
219 len += count;
220 size -= count;
221 }
187 modalias[len] = '\0'; 222 modalias[len] = '\0';
188 return len; 223 return len;
189} 224}
@@ -194,7 +229,8 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
194 * 229 *
195 * Check if the given device has an ACPI companion and if that companion has 230 * Check if the given device has an ACPI companion and if that companion has
196 * a valid list of PNP IDs, and if the device is the first (primary) physical 231 * a valid list of PNP IDs, and if the device is the first (primary) physical
197 * device associated with it. 232 * device associated with it. Return the companion pointer if that's the case
233 * or NULL otherwise.
198 * 234 *
199 * If multiple physical devices are attached to a single ACPI companion, we need 235 * If multiple physical devices are attached to a single ACPI companion, we need
200 * to be careful. The usage scenario for this kind of relationship is that all 236 * to be careful. The usage scenario for this kind of relationship is that all
@@ -208,88 +244,129 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
208 * resources available from it but they will be matched normally using functions 244 * resources available from it but they will be matched normally using functions
209 * provided by their bus types (and analogously for their modalias). 245 * provided by their bus types (and analogously for their modalias).
210 */ 246 */
211static bool acpi_companion_match(const struct device *dev) 247static struct acpi_device *acpi_companion_match(const struct device *dev)
212{ 248{
213 struct acpi_device *adev; 249 struct acpi_device *adev;
214 bool ret; 250 struct mutex *physical_node_lock;
215 251
216 adev = ACPI_COMPANION(dev); 252 adev = ACPI_COMPANION(dev);
217 if (!adev) 253 if (!adev)
218 return false; 254 return NULL;
219 255
220 if (list_empty(&adev->pnp.ids)) 256 if (list_empty(&adev->pnp.ids))
221 return false; 257 return NULL;
222 258
223 mutex_lock(&adev->physical_node_lock); 259 physical_node_lock = &adev->physical_node_lock;
260 mutex_lock(physical_node_lock);
224 if (list_empty(&adev->physical_node_list)) { 261 if (list_empty(&adev->physical_node_list)) {
225 ret = false; 262 adev = NULL;
226 } else { 263 } else {
227 const struct acpi_device_physical_node *node; 264 const struct acpi_device_physical_node *node;
228 265
229 node = list_first_entry(&adev->physical_node_list, 266 node = list_first_entry(&adev->physical_node_list,
230 struct acpi_device_physical_node, node); 267 struct acpi_device_physical_node, node);
231 ret = node->dev == dev; 268 if (node->dev != dev)
269 adev = NULL;
232 } 270 }
233 mutex_unlock(&adev->physical_node_lock); 271 mutex_unlock(physical_node_lock);
234 272
235 return ret; 273 return adev;
236} 274}
237 275
238/* 276static int __acpi_device_uevent_modalias(struct acpi_device *adev,
239 * Creates uevent modalias field for ACPI enumerated devices. 277 struct kobj_uevent_env *env)
240 * Because the other buses does not support ACPI HIDs & CIDs.
241 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
242 * "acpi:IBM0001:ACPI0001"
243 */
244int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
245{ 278{
246 int len; 279 int len;
247 280
248 if (!acpi_companion_match(dev)) 281 if (!adev)
249 return -ENODEV; 282 return -ENODEV;
250 283
284 if (list_empty(&adev->pnp.ids))
285 return 0;
286
251 if (add_uevent_var(env, "MODALIAS=")) 287 if (add_uevent_var(env, "MODALIAS="))
252 return -ENOMEM; 288 return -ENOMEM;
253 len = create_modalias(ACPI_COMPANION(dev), &env->buf[env->buflen - 1], 289
254 sizeof(env->buf) - env->buflen); 290 len = create_pnp_modalias(adev, &env->buf[env->buflen - 1],
255 if (len <= 0) 291 sizeof(env->buf) - env->buflen);
292 if (len < 0)
293 return len;
294
295 env->buflen += len;
296 if (!adev->data.of_compatible)
297 return 0;
298
299 if (len > 0 && add_uevent_var(env, "MODALIAS="))
300 return -ENOMEM;
301
302 len = create_of_modalias(adev, &env->buf[env->buflen - 1],
303 sizeof(env->buf) - env->buflen);
304 if (len < 0)
256 return len; 305 return len;
306
257 env->buflen += len; 307 env->buflen += len;
308
258 return 0; 309 return 0;
259} 310}
260EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
261 311
262/* 312/*
263 * Creates modalias sysfs attribute for ACPI enumerated devices. 313 * Creates uevent modalias field for ACPI enumerated devices.
264 * Because the other buses does not support ACPI HIDs & CIDs. 314 * Because the other buses does not support ACPI HIDs & CIDs.
265 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: 315 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
266 * "acpi:IBM0001:ACPI0001" 316 * "acpi:IBM0001:ACPI0001"
267 */ 317 */
268int acpi_device_modalias(struct device *dev, char *buf, int size) 318int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
269{ 319{
270 int len; 320 return __acpi_device_uevent_modalias(acpi_companion_match(dev), env);
321}
322EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
271 323
272 if (!acpi_companion_match(dev)) 324static int __acpi_device_modalias(struct acpi_device *adev, char *buf, int size)
325{
326 int len, count;
327
328 if (!adev)
273 return -ENODEV; 329 return -ENODEV;
274 330
275 len = create_modalias(ACPI_COMPANION(dev), buf, size -1); 331 if (list_empty(&adev->pnp.ids))
276 if (len <= 0) 332 return 0;
333
334 len = create_pnp_modalias(adev, buf, size - 1);
335 if (len < 0) {
336 return len;
337 } else if (len > 0) {
338 buf[len++] = '\n';
339 size -= len;
340 }
341 if (!adev->data.of_compatible)
277 return len; 342 return len;
278 buf[len++] = '\n'; 343
344 count = create_of_modalias(adev, buf + len, size - 1);
345 if (count < 0) {
346 return count;
347 } else if (count > 0) {
348 len += count;
349 buf[len++] = '\n';
350 }
351
279 return len; 352 return len;
280} 353}
354
355/*
356 * Creates modalias sysfs attribute for ACPI enumerated devices.
357 * Because the other buses does not support ACPI HIDs & CIDs.
358 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
359 * "acpi:IBM0001:ACPI0001"
360 */
361int acpi_device_modalias(struct device *dev, char *buf, int size)
362{
363 return __acpi_device_modalias(acpi_companion_match(dev), buf, size);
364}
281EXPORT_SYMBOL_GPL(acpi_device_modalias); 365EXPORT_SYMBOL_GPL(acpi_device_modalias);
282 366
283static ssize_t 367static ssize_t
284acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { 368acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
285 struct acpi_device *acpi_dev = to_acpi_device(dev); 369 return __acpi_device_modalias(to_acpi_device(dev), buf, 1024);
286 int len;
287
288 len = create_modalias(acpi_dev, buf, 1024);
289 if (len <= 0)
290 return len;
291 buf[len++] = '\n';
292 return len;
293} 370}
294static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); 371static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
295 372
@@ -894,8 +971,51 @@ static void acpi_device_remove_files(struct acpi_device *dev)
894 ACPI Bus operations 971 ACPI Bus operations
895 -------------------------------------------------------------------------- */ 972 -------------------------------------------------------------------------- */
896 973
974/**
975 * acpi_of_match_device - Match device object using the "compatible" property.
976 * @adev: ACPI device object to match.
977 * @of_match_table: List of device IDs to match against.
978 *
979 * If @dev has an ACPI companion which has the special PRP0001 device ID in its
980 * list of identifiers and a _DSD object with the "compatible" property, use
981 * that property to match against the given list of identifiers.
982 */
983static bool acpi_of_match_device(struct acpi_device *adev,
984 const struct of_device_id *of_match_table)
985{
986 const union acpi_object *of_compatible, *obj;
987 int i, nval;
988
989 if (!adev)
990 return false;
991
992 of_compatible = adev->data.of_compatible;
993 if (!of_match_table || !of_compatible)
994 return false;
995
996 if (of_compatible->type == ACPI_TYPE_PACKAGE) {
997 nval = of_compatible->package.count;
998 obj = of_compatible->package.elements;
999 } else { /* Must be ACPI_TYPE_STRING. */
1000 nval = 1;
1001 obj = of_compatible;
1002 }
1003 /* Now we can look for the driver DT compatible strings */
1004 for (i = 0; i < nval; i++, obj++) {
1005 const struct of_device_id *id;
1006
1007 for (id = of_match_table; id->compatible[0]; id++)
1008 if (!strcasecmp(obj->string.pointer, id->compatible))
1009 return true;
1010 }
1011
1012 return false;
1013}
1014
897static const struct acpi_device_id *__acpi_match_device( 1015static const struct acpi_device_id *__acpi_match_device(
898 struct acpi_device *device, const struct acpi_device_id *ids) 1016 struct acpi_device *device,
1017 const struct acpi_device_id *ids,
1018 const struct of_device_id *of_ids)
899{ 1019{
900 const struct acpi_device_id *id; 1020 const struct acpi_device_id *id;
901 struct acpi_hardware_id *hwid; 1021 struct acpi_hardware_id *hwid;
@@ -904,14 +1024,27 @@ static const struct acpi_device_id *__acpi_match_device(
904 * If the device is not present, it is unnecessary to load device 1024 * If the device is not present, it is unnecessary to load device
905 * driver for it. 1025 * driver for it.
906 */ 1026 */
907 if (!device->status.present) 1027 if (!device || !device->status.present)
908 return NULL; 1028 return NULL;
909 1029
910 for (id = ids; id->id[0]; id++) 1030 list_for_each_entry(hwid, &device->pnp.ids, list) {
911 list_for_each_entry(hwid, &device->pnp.ids, list) 1031 /* First, check the ACPI/PNP IDs provided by the caller. */
1032 for (id = ids; id->id[0]; id++)
912 if (!strcmp((char *) id->id, hwid->id)) 1033 if (!strcmp((char *) id->id, hwid->id))
913 return id; 1034 return id;
914 1035
1036 /*
1037 * Next, check the special "PRP0001" ID and try to match the
1038 * "compatible" property if found.
1039 *
1040 * The id returned by the below is not valid, but the only
1041 * caller passing non-NULL of_ids here is only interested in
1042 * whether or not the return value is NULL.
1043 */
1044 if (!strcmp("PRP0001", hwid->id)
1045 && acpi_of_match_device(device, of_ids))
1046 return id;
1047 }
915 return NULL; 1048 return NULL;
916} 1049}
917 1050
@@ -929,68 +1062,26 @@ static const struct acpi_device_id *__acpi_match_device(
929const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, 1062const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
930 const struct device *dev) 1063 const struct device *dev)
931{ 1064{
932 struct acpi_device *adev; 1065 return __acpi_match_device(acpi_companion_match(dev), ids, NULL);
933 acpi_handle handle = ACPI_HANDLE(dev);
934
935 if (!ids || !handle || acpi_bus_get_device(handle, &adev))
936 return NULL;
937
938 if (!acpi_companion_match(dev))
939 return NULL;
940
941 return __acpi_match_device(adev, ids);
942} 1066}
943EXPORT_SYMBOL_GPL(acpi_match_device); 1067EXPORT_SYMBOL_GPL(acpi_match_device);
944 1068
945int acpi_match_device_ids(struct acpi_device *device, 1069int acpi_match_device_ids(struct acpi_device *device,
946 const struct acpi_device_id *ids) 1070 const struct acpi_device_id *ids)
947{ 1071{
948 return __acpi_match_device(device, ids) ? 0 : -ENOENT; 1072 return __acpi_match_device(device, ids, NULL) ? 0 : -ENOENT;
949} 1073}
950EXPORT_SYMBOL(acpi_match_device_ids); 1074EXPORT_SYMBOL(acpi_match_device_ids);
951 1075
952/* Performs match against special "PRP0001" shoehorn ACPI ID */
953static bool acpi_of_driver_match_device(struct device *dev,
954 const struct device_driver *drv)
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 (!drv->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 = drv->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, 1076bool acpi_driver_match_device(struct device *dev,
988 const struct device_driver *drv) 1077 const struct device_driver *drv)
989{ 1078{
990 if (!drv->acpi_match_table) 1079 if (!drv->acpi_match_table)
991 return acpi_of_driver_match_device(dev, drv); 1080 return acpi_of_match_device(ACPI_COMPANION(dev),
1081 drv->of_match_table);
992 1082
993 return !!acpi_match_device(drv->acpi_match_table, dev); 1083 return !!__acpi_match_device(acpi_companion_match(dev),
1084 drv->acpi_match_table, drv->of_match_table);
994} 1085}
995EXPORT_SYMBOL_GPL(acpi_driver_match_device); 1086EXPORT_SYMBOL_GPL(acpi_driver_match_device);
996 1087
@@ -1031,20 +1122,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
1031 1122
1032static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) 1123static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
1033{ 1124{
1034 struct acpi_device *acpi_dev = to_acpi_device(dev); 1125 return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
1035 int len;
1036
1037 if (list_empty(&acpi_dev->pnp.ids))
1038 return 0;
1039
1040 if (add_uevent_var(env, "MODALIAS="))
1041 return -ENOMEM;
1042 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
1043 sizeof(env->buf) - env->buflen);
1044 if (len <= 0)
1045 return len;
1046 env->buflen += len;
1047 return 0;
1048} 1126}
1049 1127
1050static void acpi_device_notify(acpi_handle handle, u32 event, void *data) 1128static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
@@ -1062,10 +1140,10 @@ static void acpi_device_notify_fixed(void *data)
1062 acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); 1140 acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
1063} 1141}
1064 1142
1065static acpi_status acpi_device_fixed_event(void *data) 1143static u32 acpi_device_fixed_event(void *data)
1066{ 1144{
1067 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); 1145 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data);
1068 return AE_OK; 1146 return ACPI_INTERRUPT_HANDLED;
1069} 1147}
1070 1148
1071static int acpi_device_install_notify_handler(struct acpi_device *device) 1149static int acpi_device_install_notify_handler(struct acpi_device *device)