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