xref: /linux/drivers/acpi/glue.c (revision 8128a31eaadbcdfa37774bbd28f3f00bac69996a)
1 /*
2  * Link physical devices with ACPI devices support
3  *
4  * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
5  * Copyright (c) 2005 Intel Corp.
6  *
7  * This file is released under the GPLv2.
8  */
9 
10 #include <linux/acpi_iort.h>
11 #include <linux/export.h>
12 #include <linux/init.h>
13 #include <linux/list.h>
14 #include <linux/device.h>
15 #include <linux/slab.h>
16 #include <linux/rwsem.h>
17 #include <linux/acpi.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/platform_device.h>
20 
21 #include "internal.h"
22 
23 #define ACPI_GLUE_DEBUG	0
24 #if ACPI_GLUE_DEBUG
25 #define DBG(fmt, ...)						\
26 	printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__)
27 #else
28 #define DBG(fmt, ...)						\
29 do {								\
30 	if (0)							\
31 		printk(KERN_DEBUG PREFIX fmt, ##__VA_ARGS__);	\
32 } while (0)
33 #endif
34 static LIST_HEAD(bus_type_list);
35 static DECLARE_RWSEM(bus_type_sem);
36 
37 #define PHYSICAL_NODE_STRING "physical_node"
38 #define PHYSICAL_NODE_NAME_SIZE (sizeof(PHYSICAL_NODE_STRING) + 10)
39 
40 int register_acpi_bus_type(struct acpi_bus_type *type)
41 {
42 	if (acpi_disabled)
43 		return -ENODEV;
44 	if (type && type->match && type->find_companion) {
45 		down_write(&bus_type_sem);
46 		list_add_tail(&type->list, &bus_type_list);
47 		up_write(&bus_type_sem);
48 		printk(KERN_INFO PREFIX "bus type %s registered\n", type->name);
49 		return 0;
50 	}
51 	return -ENODEV;
52 }
53 EXPORT_SYMBOL_GPL(register_acpi_bus_type);
54 
55 int unregister_acpi_bus_type(struct acpi_bus_type *type)
56 {
57 	if (acpi_disabled)
58 		return 0;
59 	if (type) {
60 		down_write(&bus_type_sem);
61 		list_del_init(&type->list);
62 		up_write(&bus_type_sem);
63 		printk(KERN_INFO PREFIX "bus type %s unregistered\n",
64 		       type->name);
65 		return 0;
66 	}
67 	return -ENODEV;
68 }
69 EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
70 
71 static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
72 {
73 	struct acpi_bus_type *tmp, *ret = NULL;
74 
75 	down_read(&bus_type_sem);
76 	list_for_each_entry(tmp, &bus_type_list, list) {
77 		if (tmp->match(dev)) {
78 			ret = tmp;
79 			break;
80 		}
81 	}
82 	up_read(&bus_type_sem);
83 	return ret;
84 }
85 
86 #define FIND_CHILD_MIN_SCORE	1
87 #define FIND_CHILD_MAX_SCORE	2
88 
89 static int find_child_checks(struct acpi_device *adev, bool check_children)
90 {
91 	bool sta_present = true;
92 	unsigned long long sta;
93 	acpi_status status;
94 
95 	status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
96 	if (status == AE_NOT_FOUND)
97 		sta_present = false;
98 	else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
99 		return -ENODEV;
100 
101 	if (check_children && list_empty(&adev->children))
102 		return -ENODEV;
103 
104 	/*
105 	 * If the device has a _HID returning a valid ACPI/PNP device ID, it is
106 	 * better to make it look less attractive here, so that the other device
107 	 * with the same _ADR value (that may not have a valid device ID) can be
108 	 * matched going forward.  [This means a second spec violation in a row,
109 	 * so whatever we do here is best effort anyway.]
110 	 */
111 	return sta_present && !adev->pnp.type.platform_id ?
112 			FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
113 }
114 
115 struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
116 					   u64 address, bool check_children)
117 {
118 	struct acpi_device *adev, *ret = NULL;
119 	int ret_score = 0;
120 
121 	if (!parent)
122 		return NULL;
123 
124 	list_for_each_entry(adev, &parent->children, node) {
125 		unsigned long long addr;
126 		acpi_status status;
127 		int score;
128 
129 		status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR,
130 					       NULL, &addr);
131 		if (ACPI_FAILURE(status) || addr != address)
132 			continue;
133 
134 		if (!ret) {
135 			/* This is the first matching object.  Save it. */
136 			ret = adev;
137 			continue;
138 		}
139 		/*
140 		 * There is more than one matching device object with the same
141 		 * _ADR value.  That really is unexpected, so we are kind of
142 		 * beyond the scope of the spec here.  We have to choose which
143 		 * one to return, though.
144 		 *
145 		 * First, check if the previously found object is good enough
146 		 * and return it if so.  Second, do the same for the object that
147 		 * we've just found.
148 		 */
149 		if (!ret_score) {
150 			ret_score = find_child_checks(ret, check_children);
151 			if (ret_score == FIND_CHILD_MAX_SCORE)
152 				return ret;
153 		}
154 		score = find_child_checks(adev, check_children);
155 		if (score == FIND_CHILD_MAX_SCORE) {
156 			return adev;
157 		} else if (score > ret_score) {
158 			ret = adev;
159 			ret_score = score;
160 		}
161 	}
162 	return ret;
163 }
164 EXPORT_SYMBOL_GPL(acpi_find_child_device);
165 
166 static void acpi_physnode_link_name(char *buf, unsigned int node_id)
167 {
168 	if (node_id > 0)
169 		snprintf(buf, PHYSICAL_NODE_NAME_SIZE,
170 			 PHYSICAL_NODE_STRING "%u", node_id);
171 	else
172 		strcpy(buf, PHYSICAL_NODE_STRING);
173 }
174 
175 int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
176 {
177 	struct acpi_device_physical_node *physical_node, *pn;
178 	char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
179 	struct list_head *physnode_list;
180 	unsigned int node_id;
181 	int retval = -EINVAL;
182 	enum dev_dma_attr attr;
183 
184 	if (has_acpi_companion(dev)) {
185 		if (acpi_dev) {
186 			dev_warn(dev, "ACPI companion already set\n");
187 			return -EINVAL;
188 		} else {
189 			acpi_dev = ACPI_COMPANION(dev);
190 		}
191 	}
192 	if (!acpi_dev)
193 		return -EINVAL;
194 
195 	get_device(&acpi_dev->dev);
196 	get_device(dev);
197 	physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL);
198 	if (!physical_node) {
199 		retval = -ENOMEM;
200 		goto err;
201 	}
202 
203 	mutex_lock(&acpi_dev->physical_node_lock);
204 
205 	/*
206 	 * Keep the list sorted by node_id so that the IDs of removed nodes can
207 	 * be recycled easily.
208 	 */
209 	physnode_list = &acpi_dev->physical_node_list;
210 	node_id = 0;
211 	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
212 		/* Sanity check. */
213 		if (pn->dev == dev) {
214 			mutex_unlock(&acpi_dev->physical_node_lock);
215 
216 			dev_warn(dev, "Already associated with ACPI node\n");
217 			kfree(physical_node);
218 			if (ACPI_COMPANION(dev) != acpi_dev)
219 				goto err;
220 
221 			put_device(dev);
222 			put_device(&acpi_dev->dev);
223 			return 0;
224 		}
225 		if (pn->node_id == node_id) {
226 			physnode_list = &pn->node;
227 			node_id++;
228 		}
229 	}
230 
231 	physical_node->node_id = node_id;
232 	physical_node->dev = dev;
233 	list_add(&physical_node->node, physnode_list);
234 	acpi_dev->physical_node_count++;
235 
236 	if (!has_acpi_companion(dev))
237 		ACPI_COMPANION_SET(dev, acpi_dev);
238 
239 	attr = acpi_get_dma_attr(acpi_dev);
240 	if (attr != DEV_DMA_NOT_SUPPORTED)
241 		acpi_dma_configure(dev, attr);
242 
243 	acpi_physnode_link_name(physical_node_name, node_id);
244 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
245 				   physical_node_name);
246 	if (retval)
247 		dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",
248 			physical_node_name, retval);
249 
250 	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
251 				   "firmware_node");
252 	if (retval)
253 		dev_err(dev, "Failed to create link firmware_node (%d)\n",
254 			retval);
255 
256 	mutex_unlock(&acpi_dev->physical_node_lock);
257 
258 	if (acpi_dev->wakeup.flags.valid)
259 		device_set_wakeup_capable(dev, true);
260 
261 	return 0;
262 
263  err:
264 	ACPI_COMPANION_SET(dev, NULL);
265 	put_device(dev);
266 	put_device(&acpi_dev->dev);
267 	return retval;
268 }
269 EXPORT_SYMBOL_GPL(acpi_bind_one);
270 
271 int acpi_unbind_one(struct device *dev)
272 {
273 	struct acpi_device *acpi_dev = ACPI_COMPANION(dev);
274 	struct acpi_device_physical_node *entry;
275 
276 	if (!acpi_dev)
277 		return 0;
278 
279 	mutex_lock(&acpi_dev->physical_node_lock);
280 
281 	list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
282 		if (entry->dev == dev) {
283 			char physnode_name[PHYSICAL_NODE_NAME_SIZE];
284 
285 			list_del(&entry->node);
286 			acpi_dev->physical_node_count--;
287 
288 			acpi_physnode_link_name(physnode_name, entry->node_id);
289 			sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
290 			sysfs_remove_link(&dev->kobj, "firmware_node");
291 			ACPI_COMPANION_SET(dev, NULL);
292 			/* Drop references taken by acpi_bind_one(). */
293 			put_device(dev);
294 			put_device(&acpi_dev->dev);
295 			kfree(entry);
296 			break;
297 		}
298 
299 	mutex_unlock(&acpi_dev->physical_node_lock);
300 	return 0;
301 }
302 EXPORT_SYMBOL_GPL(acpi_unbind_one);
303 
304 static int acpi_platform_notify(struct device *dev)
305 {
306 	struct acpi_bus_type *type = acpi_get_bus_type(dev);
307 	struct acpi_device *adev;
308 	int ret;
309 
310 	ret = acpi_bind_one(dev, NULL);
311 	if (ret && type) {
312 		struct acpi_device *adev;
313 
314 		adev = type->find_companion(dev);
315 		if (!adev) {
316 			DBG("Unable to get handle for %s\n", dev_name(dev));
317 			ret = -ENODEV;
318 			goto out;
319 		}
320 		ret = acpi_bind_one(dev, adev);
321 		if (ret)
322 			goto out;
323 	}
324 	adev = ACPI_COMPANION(dev);
325 	if (!adev)
326 		goto out;
327 
328 	if (dev->bus == &platform_bus_type)
329 		acpi_configure_pmsi_domain(dev);
330 
331 	if (type && type->setup)
332 		type->setup(dev);
333 	else if (adev->handler && adev->handler->bind)
334 		adev->handler->bind(dev);
335 
336  out:
337 #if ACPI_GLUE_DEBUG
338 	if (!ret) {
339 		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
340 
341 		acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer);
342 		DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer);
343 		kfree(buffer.pointer);
344 	} else
345 		DBG("Device %s -> No ACPI support\n", dev_name(dev));
346 #endif
347 
348 	return ret;
349 }
350 
351 static int acpi_platform_notify_remove(struct device *dev)
352 {
353 	struct acpi_device *adev = ACPI_COMPANION(dev);
354 	struct acpi_bus_type *type;
355 
356 	if (!adev)
357 		return 0;
358 
359 	type = acpi_get_bus_type(dev);
360 	if (type && type->cleanup)
361 		type->cleanup(dev);
362 	else if (adev->handler && adev->handler->unbind)
363 		adev->handler->unbind(dev);
364 
365 	acpi_unbind_one(dev);
366 	return 0;
367 }
368 
369 void __init init_acpi_device_notify(void)
370 {
371 	if (platform_notify || platform_notify_remove) {
372 		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
373 		return;
374 	}
375 	platform_notify = acpi_platform_notify;
376 	platform_notify_remove = acpi_platform_notify_remove;
377 }
378