xref: /linux/drivers/acpi/glue.c (revision ea9102cae4a634a752749dda4914cb235910134e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Link physical devices with ACPI devices support
4  *
5  * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
6  * Copyright (c) 2005 Intel Corp.
7  */
8 
9 #define pr_fmt(fmt) "ACPI: " fmt
10 
11 #include <linux/acpi_iort.h>
12 #include <linux/export.h>
13 #include <linux/init.h>
14 #include <linux/list.h>
15 #include <linux/device.h>
16 #include <linux/slab.h>
17 #include <linux/rwsem.h>
18 #include <linux/acpi.h>
19 #include <linux/dma-mapping.h>
20 #include <linux/pci.h>
21 #include <linux/pci-acpi.h>
22 #include <linux/platform_device.h>
23 
24 #include "internal.h"
25 
26 static LIST_HEAD(bus_type_list);
27 static DECLARE_RWSEM(bus_type_sem);
28 
29 #define PHYSICAL_NODE_STRING "physical_node"
30 #define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
31 
32 int register_acpi_bus_type(struct acpi_bus_type *type)
33 {
34 	if (acpi_disabled)
35 		return -ENODEV;
36 	if (type && type->match && type->find_companion) {
37 		down_write(&bus_type_sem);
38 		list_add_tail(&type->list, &bus_type_list);
39 		up_write(&bus_type_sem);
40 		pr_info("bus type %s registered\n", type->name);
41 		return 0;
42 	}
43 	return -ENODEV;
44 }
45 EXPORT_SYMBOL_GPL(register_acpi_bus_type);
46 
47 int unregister_acpi_bus_type(struct acpi_bus_type *type)
48 {
49 	if (acpi_disabled)
50 		return 0;
51 	if (type) {
52 		down_write(&bus_type_sem);
53 		list_del_init(&type->list);
54 		up_write(&bus_type_sem);
55 		pr_info("bus type %s unregistered\n", type->name);
56 		return 0;
57 	}
58 	return -ENODEV;
59 }
60 EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
61 
62 static struct acpi_device *acpi_companion_lookup(struct device *dev)
63 {
64 	struct acpi_bus_type *type;
65 
66 	if (!dev->type)
67 		return NULL;
68 
69 	guard(rwsem_read)(&bus_type_sem);
70 
71 	list_for_each_entry(type, &bus_type_list, list) {
72 		struct acpi_device *adev;
73 
74 		if (!type->match(dev))
75 			continue;
76 
77 		adev = type->find_companion(dev);
78 		if (!adev) {
79 			dev_dbg(dev, "ACPI companion not found\n");
80 			return NULL;
81 		}
82 		if (acpi_bind_one(dev, adev)) {
83 			dev_dbg(dev, "Binding to ACPI companion failed\n");
84 			return NULL;
85 		}
86 		if (type->setup)
87 			type->setup(dev);
88 
89 		return adev;
90 	}
91 
92 	return NULL;
93 }
94 
95 #define FIND_CHILD_MIN_SCORE	1
96 #define FIND_CHILD_MID_SCORE	2
97 #define FIND_CHILD_MAX_SCORE	3
98 
99 static int match_any(struct acpi_device *adev, void *not_used)
100 {
101 	return 1;
102 }
103 
104 static bool acpi_dev_has_children(struct acpi_device *adev)
105 {
106 	return acpi_dev_for_each_child(adev, match_any, NULL) > 0;
107 }
108 
109 static int find_child_checks(struct acpi_device *adev, bool check_children)
110 {
111 	unsigned long long sta;
112 	acpi_status status;
113 
114 	if (check_children && !acpi_dev_has_children(adev))
115 		return -ENODEV;
116 
117 	status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
118 	if (status == AE_NOT_FOUND) {
119 		/*
120 		 * Special case: backlight device objects without _STA are
121 		 * preferred to other objects with the same _ADR value, because
122 		 * it is more likely that they are actually useful.
123 		 */
124 		if (adev->pnp.type.backlight)
125 			return FIND_CHILD_MID_SCORE;
126 
127 		return FIND_CHILD_MIN_SCORE;
128 	}
129 
130 	if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
131 		return -ENODEV;
132 
133 	/*
134 	 * If the device has a _HID returning a valid ACPI/PNP device ID, it is
135 	 * better to make it look less attractive here, so that the other device
136 	 * with the same _ADR value (that may not have a valid device ID) can be
137 	 * matched going forward.  [This means a second spec violation in a row,
138 	 * so whatever we do here is best effort anyway.]
139 	 */
140 	if (adev->pnp.type.platform_id)
141 		return FIND_CHILD_MIN_SCORE;
142 
143 	return FIND_CHILD_MAX_SCORE;
144 }
145 
146 struct find_child_walk_data {
147 	struct acpi_device *adev;
148 	u64 address;
149 	int score;
150 	bool check_sta;
151 	bool check_children;
152 };
153 
154 static int check_one_child(struct acpi_device *adev, void *data)
155 {
156 	struct find_child_walk_data *wd = data;
157 	int score;
158 
159 	if (!adev->pnp.type.bus_address || acpi_device_adr(adev) != wd->address)
160 		return 0;
161 
162 	if (!wd->adev) {
163 		/*
164 		 * This is the first matching object, so save it.  If it is not
165 		 * necessary to look for any other matching objects, stop the
166 		 * search.
167 		 */
168 		wd->adev = adev;
169 		return !(wd->check_sta || wd->check_children);
170 	}
171 
172 	/*
173 	 * There is more than one matching device object with the same _ADR
174 	 * value.  That really is unexpected, so we are kind of beyond the scope
175 	 * of the spec here.  We have to choose which one to return, though.
176 	 *
177 	 * First, get the score for the previously found object and terminate
178 	 * the walk if it is maximum.
179 	*/
180 	if (!wd->score) {
181 		score = find_child_checks(wd->adev, wd->check_children);
182 		if (score == FIND_CHILD_MAX_SCORE)
183 			return 1;
184 
185 		wd->score = score;
186 	}
187 	/*
188 	 * Second, if the object that has just been found has a better score,
189 	 * replace the previously found one with it and terminate the walk if
190 	 * the new score is maximum.
191 	 */
192 	score = find_child_checks(adev, wd->check_children);
193 	if (score > wd->score) {
194 		wd->adev = adev;
195 		if (score == FIND_CHILD_MAX_SCORE)
196 			return 1;
197 
198 		wd->score = score;
199 	}
200 
201 	/* Continue, because there may be better matches. */
202 	return 0;
203 }
204 
205 static struct acpi_device *acpi_find_child(struct acpi_device *parent,
206 					   u64 address, bool check_children,
207 					   bool check_sta)
208 {
209 	struct find_child_walk_data wd = {
210 		.address = address,
211 		.check_children = check_children,
212 		.check_sta = check_sta,
213 		.adev = NULL,
214 		.score = 0,
215 	};
216 
217 	if (parent)
218 		acpi_dev_for_each_child(parent, check_one_child, &wd);
219 
220 	return wd.adev;
221 }
222 
223 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
224 					   u64 address, bool check_children)
225 {
226 	return acpi_find_child(parent, address, check_children, true);
227 }
228 EXPORT_SYMBOL_GPL(acpi_find_child_device);
229 
230 struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev,
231 					   acpi_bus_address adr)
232 {
233 	return acpi_find_child(adev, adr, false, false);
234 }
235 EXPORT_SYMBOL_GPL(acpi_find_child_by_adr);
236 
237 static void acpi_physnode_link_name(char *buf, unsigned int node_id)
238 {
239 	if (node_id > 0)
240 		snprintf(buf, PHYSICAL_NODE_NAME_SIZE,
241 			 PHYSICAL_NODE_STRING "%u", node_id);
242 	else
243 		strcpy(buf, PHYSICAL_NODE_STRING);
244 }
245 
246 int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
247 {
248 	struct acpi_device_physical_node *physical_node, *pn;
249 	struct acpi_device *comp_dev = ACPI_COMPANION(dev);
250 	char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
251 	struct list_head *physnode_list;
252 	unsigned int node_id;
253 	int retval = -EINVAL;
254 
255 	if (!acpi_dev) {
256 		if (!comp_dev)
257 			return -EINVAL;
258 
259 		/* If the companion has been set upfront, pick it up. */
260 		acpi_dev = comp_dev;
261 	} else if (comp_dev && acpi_dev != comp_dev) {
262 		dev_warn(dev, "ACPI companion already set to %s which is not %s\n",
263 			 acpi_dev_name(comp_dev), acpi_dev_name(acpi_dev));
264 		return -EEXIST;
265 	}
266 
267 	guard(mutex)(&acpi_dev->physical_node_lock);
268 
269 	/*
270 	 * Keep the list sorted by node_id so that the IDs of removed nodes can
271 	 * be recycled easily.
272 	 */
273 	physnode_list = &acpi_dev->physical_node_list;
274 	node_id = 0;
275 	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
276 		/* Sanity check. */
277 		if (pn->dev == dev) {
278 			if (!comp_dev) {
279 				/* Really unexpected. */
280 				ACPI_COMPANION_SET(dev, acpi_dev);
281 				dev_warn(&acpi_dev->dev,
282 					 "Physical device list corruption fixed up\n");
283 			}
284 			return 0;
285 		}
286 		if (pn->node_id == node_id) {
287 			physnode_list = &pn->node;
288 			node_id++;
289 		}
290 	}
291 
292 	physical_node = kzalloc_obj(*physical_node);
293 	if (!physical_node)
294 		return -ENOMEM;
295 
296 	acpi_dev_get(acpi_dev);
297 	get_device(dev);
298 
299 	physical_node->node_id = node_id;
300 	physical_node->dev = dev;
301 	list_add(&physical_node->node, physnode_list);
302 	acpi_dev->physical_node_count++;
303 
304 	if (!comp_dev)
305 		ACPI_COMPANION_SET(dev, acpi_dev);
306 
307 	acpi_physnode_link_name(physical_node_name, node_id);
308 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
309 				   physical_node_name);
310 	if (retval)
311 		dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",
312 			physical_node_name, retval);
313 
314 	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
315 				   "firmware_node");
316 	if (retval)
317 		dev_err(dev, "Failed to create link firmware_node (%d)\n",
318 			retval);
319 
320 	if (acpi_dev->wakeup.flags.valid)
321 		device_set_wakeup_capable(dev, true);
322 
323 	return 0;
324 }
325 EXPORT_SYMBOL_GPL(acpi_bind_one);
326 
327 void acpi_unbind_one(struct device *dev)
328 {
329 	struct acpi_device *acpi_dev = ACPI_COMPANION(dev);
330 	struct acpi_device_physical_node *entry;
331 
332 	if (!acpi_dev)
333 		return;
334 
335 	mutex_lock(&acpi_dev->physical_node_lock);
336 
337 	list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
338 		if (entry->dev == dev) {
339 			char physnode_name[PHYSICAL_NODE_NAME_SIZE];
340 
341 			list_del(&entry->node);
342 			acpi_dev->physical_node_count--;
343 
344 			acpi_physnode_link_name(physnode_name, entry->node_id);
345 			sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
346 			sysfs_remove_link(&dev->kobj, "firmware_node");
347 			ACPI_COMPANION_SET(dev, NULL);
348 
349 			mutex_unlock(&acpi_dev->physical_node_lock);
350 
351 			/* Drop references taken by acpi_bind_one(). */
352 			put_device(dev);
353 			acpi_dev_put(acpi_dev);
354 			kfree(entry);
355 			return;
356 		}
357 
358 	mutex_unlock(&acpi_dev->physical_node_lock);
359 }
360 EXPORT_SYMBOL_GPL(acpi_unbind_one);
361 
362 void acpi_device_notify(struct device *dev)
363 {
364 	struct acpi_device *adev;
365 	int ret;
366 
367 	/* ACPI devices have no ACPI companions. */
368 	if (dev->bus == &acpi_bus_type)
369 		return;
370 
371 	ret = acpi_bind_one(dev, NULL);
372 	if (ret) {
373 		adev = acpi_companion_lookup(dev);
374 		if (!adev)
375 			return;
376 	} else {
377 		adev = ACPI_COMPANION(dev);
378 
379 		if (dev_is_pci(dev)) {
380 			pci_acpi_setup(dev, adev);
381 		} else if (dev_is_platform(dev)) {
382 			acpi_configure_pmsi_domain(dev);
383 
384 			if (adev->handler && adev->handler->bind)
385 				adev->handler->bind(dev);
386 		}
387 	}
388 
389 	dev_dbg(dev, "Bound to ACPI device %s\n", acpi_dev_name(adev));
390 }
391 
392 void acpi_device_notify_remove(struct device *dev)
393 {
394 	struct acpi_device *adev = ACPI_COMPANION(dev);
395 
396 	if (!adev)
397 		return;
398 
399 	if (dev_is_pci(dev))
400 		pci_acpi_cleanup(dev, adev);
401 	else if (adev->handler && adev->handler->unbind)
402 		adev->handler->unbind(dev);
403 
404 	acpi_unbind_one(dev);
405 }
406