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 return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE; 102 } 103 104 struct acpi_device *acpi_find_child_device(struct acpi_device *parent, 105 u64 address, bool check_children) 106 { 107 struct acpi_device *adev, *ret = NULL; 108 int ret_score = 0; 109 110 if (!parent) 111 return NULL; 112 113 list_for_each_entry(adev, &parent->children, node) { 114 unsigned long long addr; 115 acpi_status status; 116 int score; 117 118 status = acpi_evaluate_integer(adev->handle, METHOD_NAME__ADR, 119 NULL, &addr); 120 if (ACPI_FAILURE(status) || addr != address) 121 continue; 122 123 if (!ret) { 124 /* This is the first matching object. Save it. */ 125 ret = adev; 126 continue; 127 } 128 /* 129 * There is more than one matching device object with the same 130 * _ADR value. That really is unexpected, so we are kind of 131 * beyond the scope of the spec here. We have to choose which 132 * one to return, though. 133 * 134 * First, check if the previously found object is good enough 135 * and return it if so. Second, do the same for the object that 136 * we've just found. 137 */ 138 if (!ret_score) { 139 ret_score = find_child_checks(ret, check_children); 140 if (ret_score == FIND_CHILD_MAX_SCORE) 141 return ret; 142 } 143 score = find_child_checks(adev, check_children); 144 if (score == FIND_CHILD_MAX_SCORE) { 145 return adev; 146 } else if (score > ret_score) { 147 ret = adev; 148 ret_score = score; 149 } 150 } 151 return ret; 152 } 153 EXPORT_SYMBOL_GPL(acpi_find_child_device); 154 155 static void acpi_physnode_link_name(char *buf, unsigned int node_id) 156 { 157 if (node_id > 0) 158 snprintf(buf, PHYSICAL_NODE_NAME_SIZE, 159 PHYSICAL_NODE_STRING "%u", node_id); 160 else 161 strcpy(buf, PHYSICAL_NODE_STRING); 162 } 163 164 int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) 165 { 166 struct acpi_device_physical_node *physical_node, *pn; 167 char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; 168 struct list_head *physnode_list; 169 unsigned int node_id; 170 int retval = -EINVAL; 171 enum dev_dma_attr attr; 172 173 if (has_acpi_companion(dev)) { 174 if (acpi_dev) { 175 dev_warn(dev, "ACPI companion already set\n"); 176 return -EINVAL; 177 } else { 178 acpi_dev = ACPI_COMPANION(dev); 179 } 180 } 181 if (!acpi_dev) 182 return -EINVAL; 183 184 get_device(&acpi_dev->dev); 185 get_device(dev); 186 physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); 187 if (!physical_node) { 188 retval = -ENOMEM; 189 goto err; 190 } 191 192 mutex_lock(&acpi_dev->physical_node_lock); 193 194 /* 195 * Keep the list sorted by node_id so that the IDs of removed nodes can 196 * be recycled easily. 197 */ 198 physnode_list = &acpi_dev->physical_node_list; 199 node_id = 0; 200 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { 201 /* Sanity check. */ 202 if (pn->dev == dev) { 203 mutex_unlock(&acpi_dev->physical_node_lock); 204 205 dev_warn(dev, "Already associated with ACPI node\n"); 206 kfree(physical_node); 207 if (ACPI_COMPANION(dev) != acpi_dev) 208 goto err; 209 210 put_device(dev); 211 put_device(&acpi_dev->dev); 212 return 0; 213 } 214 if (pn->node_id == node_id) { 215 physnode_list = &pn->node; 216 node_id++; 217 } 218 } 219 220 physical_node->node_id = node_id; 221 physical_node->dev = dev; 222 list_add(&physical_node->node, physnode_list); 223 acpi_dev->physical_node_count++; 224 225 if (!has_acpi_companion(dev)) 226 ACPI_COMPANION_SET(dev, acpi_dev); 227 228 attr = acpi_get_dma_attr(acpi_dev); 229 if (attr != DEV_DMA_NOT_SUPPORTED) 230 arch_setup_dma_ops(dev, 0, 0, NULL, 231 attr == DEV_DMA_COHERENT); 232 233 acpi_physnode_link_name(physical_node_name, node_id); 234 retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 235 physical_node_name); 236 if (retval) 237 dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n", 238 physical_node_name, retval); 239 240 retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, 241 "firmware_node"); 242 if (retval) 243 dev_err(dev, "Failed to create link firmware_node (%d)\n", 244 retval); 245 246 mutex_unlock(&acpi_dev->physical_node_lock); 247 248 if (acpi_dev->wakeup.flags.valid) 249 device_set_wakeup_capable(dev, true); 250 251 return 0; 252 253 err: 254 ACPI_COMPANION_SET(dev, NULL); 255 put_device(dev); 256 put_device(&acpi_dev->dev); 257 return retval; 258 } 259 EXPORT_SYMBOL_GPL(acpi_bind_one); 260 261 int acpi_unbind_one(struct device *dev) 262 { 263 struct acpi_device *acpi_dev = ACPI_COMPANION(dev); 264 struct acpi_device_physical_node *entry; 265 266 if (!acpi_dev) 267 return 0; 268 269 mutex_lock(&acpi_dev->physical_node_lock); 270 271 list_for_each_entry(entry, &acpi_dev->physical_node_list, node) 272 if (entry->dev == dev) { 273 char physnode_name[PHYSICAL_NODE_NAME_SIZE]; 274 275 list_del(&entry->node); 276 acpi_dev->physical_node_count--; 277 278 acpi_physnode_link_name(physnode_name, entry->node_id); 279 sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); 280 sysfs_remove_link(&dev->kobj, "firmware_node"); 281 ACPI_COMPANION_SET(dev, NULL); 282 /* Drop references taken by acpi_bind_one(). */ 283 put_device(dev); 284 put_device(&acpi_dev->dev); 285 kfree(entry); 286 break; 287 } 288 289 mutex_unlock(&acpi_dev->physical_node_lock); 290 return 0; 291 } 292 EXPORT_SYMBOL_GPL(acpi_unbind_one); 293 294 static int acpi_platform_notify(struct device *dev) 295 { 296 struct acpi_bus_type *type = acpi_get_bus_type(dev); 297 struct acpi_device *adev; 298 int ret; 299 300 ret = acpi_bind_one(dev, NULL); 301 if (ret && type) { 302 struct acpi_device *adev; 303 304 adev = type->find_companion(dev); 305 if (!adev) { 306 DBG("Unable to get handle for %s\n", dev_name(dev)); 307 ret = -ENODEV; 308 goto out; 309 } 310 ret = acpi_bind_one(dev, adev); 311 if (ret) 312 goto out; 313 } 314 adev = ACPI_COMPANION(dev); 315 if (!adev) 316 goto out; 317 318 if (type && type->setup) 319 type->setup(dev); 320 else if (adev->handler && adev->handler->bind) 321 adev->handler->bind(dev); 322 323 out: 324 #if ACPI_GLUE_DEBUG 325 if (!ret) { 326 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 327 328 acpi_get_name(ACPI_HANDLE(dev), ACPI_FULL_PATHNAME, &buffer); 329 DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); 330 kfree(buffer.pointer); 331 } else 332 DBG("Device %s -> No ACPI support\n", dev_name(dev)); 333 #endif 334 335 return ret; 336 } 337 338 static int acpi_platform_notify_remove(struct device *dev) 339 { 340 struct acpi_device *adev = ACPI_COMPANION(dev); 341 struct acpi_bus_type *type; 342 343 if (!adev) 344 return 0; 345 346 type = acpi_get_bus_type(dev); 347 if (type && type->cleanup) 348 type->cleanup(dev); 349 else if (adev->handler && adev->handler->unbind) 350 adev->handler->unbind(dev); 351 352 acpi_unbind_one(dev); 353 return 0; 354 } 355 356 void __init init_acpi_device_notify(void) 357 { 358 if (platform_notify || platform_notify_remove) { 359 printk(KERN_ERR PREFIX "Can't use platform_notify\n"); 360 return; 361 } 362 platform_notify = acpi_platform_notify; 363 platform_notify_remove = acpi_platform_notify_remove; 364 } 365