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 183 if (has_acpi_companion(dev)) { 184 if (acpi_dev) { 185 dev_warn(dev, "ACPI companion already set\n"); 186 return -EINVAL; 187 } else { 188 acpi_dev = ACPI_COMPANION(dev); 189 } 190 } 191 if (!acpi_dev) 192 return -EINVAL; 193 194 get_device(&acpi_dev->dev); 195 get_device(dev); 196 physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); 197 if (!physical_node) { 198 retval = -ENOMEM; 199 goto err; 200 } 201 202 mutex_lock(&acpi_dev->physical_node_lock); 203 204 /* 205 * Keep the list sorted by node_id so that the IDs of removed nodes can 206 * be recycled easily. 207 */ 208 physnode_list = &acpi_dev->physical_node_list; 209 node_id = 0; 210 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { 211 /* Sanity check. */ 212 if (pn->dev == dev) { 213 mutex_unlock(&acpi_dev->physical_node_lock); 214 215 dev_warn(dev, "Already associated with ACPI node\n"); 216 kfree(physical_node); 217 if (ACPI_COMPANION(dev) != acpi_dev) 218 goto err; 219 220 put_device(dev); 221 put_device(&acpi_dev->dev); 222 return 0; 223 } 224 if (pn->node_id == node_id) { 225 physnode_list = &pn->node; 226 node_id++; 227 } 228 } 229 230 physical_node->node_id = node_id; 231 physical_node->dev = dev; 232 list_add(&physical_node->node, physnode_list); 233 acpi_dev->physical_node_count++; 234 235 if (!has_acpi_companion(dev)) 236 ACPI_COMPANION_SET(dev, acpi_dev); 237 238 acpi_physnode_link_name(physical_node_name, node_id); 239 retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 240 physical_node_name); 241 if (retval) 242 dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n", 243 physical_node_name, retval); 244 245 retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, 246 "firmware_node"); 247 if (retval) 248 dev_err(dev, "Failed to create link firmware_node (%d)\n", 249 retval); 250 251 mutex_unlock(&acpi_dev->physical_node_lock); 252 253 if (acpi_dev->wakeup.flags.valid) 254 device_set_wakeup_capable(dev, true); 255 256 return 0; 257 258 err: 259 ACPI_COMPANION_SET(dev, NULL); 260 put_device(dev); 261 put_device(&acpi_dev->dev); 262 return retval; 263 } 264 EXPORT_SYMBOL_GPL(acpi_bind_one); 265 266 int acpi_unbind_one(struct device *dev) 267 { 268 struct acpi_device *acpi_dev = ACPI_COMPANION(dev); 269 struct acpi_device_physical_node *entry; 270 271 if (!acpi_dev) 272 return 0; 273 274 mutex_lock(&acpi_dev->physical_node_lock); 275 276 list_for_each_entry(entry, &acpi_dev->physical_node_list, node) 277 if (entry->dev == dev) { 278 char physnode_name[PHYSICAL_NODE_NAME_SIZE]; 279 280 list_del(&entry->node); 281 acpi_dev->physical_node_count--; 282 283 acpi_physnode_link_name(physnode_name, entry->node_id); 284 sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); 285 sysfs_remove_link(&dev->kobj, "firmware_node"); 286 ACPI_COMPANION_SET(dev, NULL); 287 /* Drop references taken by acpi_bind_one(). */ 288 put_device(dev); 289 put_device(&acpi_dev->dev); 290 kfree(entry); 291 break; 292 } 293 294 mutex_unlock(&acpi_dev->physical_node_lock); 295 return 0; 296 } 297 EXPORT_SYMBOL_GPL(acpi_unbind_one); 298 299 static int acpi_platform_notify(struct device *dev) 300 { 301 struct acpi_bus_type *type = acpi_get_bus_type(dev); 302 struct acpi_device *adev; 303 int ret; 304 305 ret = acpi_bind_one(dev, NULL); 306 if (ret && type) { 307 struct acpi_device *adev; 308 309 adev = type->find_companion(dev); 310 if (!adev) { 311 DBG("Unable to get handle for %s\n", dev_name(dev)); 312 ret = -ENODEV; 313 goto out; 314 } 315 ret = acpi_bind_one(dev, adev); 316 if (ret) 317 goto out; 318 } 319 adev = ACPI_COMPANION(dev); 320 if (!adev) 321 goto out; 322 323 if (dev->bus == &platform_bus_type) 324 acpi_configure_pmsi_domain(dev); 325 326 if (type && type->setup) 327 type->setup(dev); 328 else if (adev->handler && adev->handler->bind) 329 adev->handler->bind(dev); 330 331 out: 332 #if ACPI_GLUE_DEBUG 333 if (!ret) { 334 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 335 336 acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer); 337 DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); 338 kfree(buffer.pointer); 339 } else 340 DBG("Device %s -> No ACPI support\n", dev_name(dev)); 341 #endif 342 343 return ret; 344 } 345 346 static int acpi_platform_notify_remove(struct device *dev) 347 { 348 struct acpi_device *adev = ACPI_COMPANION(dev); 349 struct acpi_bus_type *type; 350 351 if (!adev) 352 return 0; 353 354 type = acpi_get_bus_type(dev); 355 if (type && type->cleanup) 356 type->cleanup(dev); 357 else if (adev->handler && adev->handler->unbind) 358 adev->handler->unbind(dev); 359 360 acpi_unbind_one(dev); 361 return 0; 362 } 363 364 void __init init_acpi_device_notify(void) 365 { 366 if (platform_notify || platform_notify_remove) { 367 printk(KERN_ERR PREFIX "Can't use platform_notify\n"); 368 return; 369 } 370 platform_notify = acpi_platform_notify; 371 platform_notify_remove = acpi_platform_notify_remove; 372 } 373