Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'device-properties'

* device-properties:
ACPI / property: Fix subnode lookup scope for data-only subnodes
acpi-dma: Add support for "dma-names" device property
device property: Add fwnode_property_match_string()
ACPI / property: Extend device_get_next_child_node() to data-only nodes
ACPI / gpio: Split acpi_get_gpiod_by_index()
ACPI / property: Extend fwnode_property_* to data-only subnodes
ACPI / property: Expose data-only subnodes via sysfs
ACPI / property: Add support for data-only subnodes
ACPI / property: Add routine for extraction of _DSD properties

+764 -198
+108 -12
drivers/acpi/device_sysfs.c
··· 26 26 27 27 #include "internal.h" 28 28 29 + static ssize_t acpi_object_path(acpi_handle handle, char *buf) 30 + { 31 + struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; 32 + int result; 33 + 34 + result = acpi_get_name(handle, ACPI_FULL_PATHNAME, &path); 35 + if (result) 36 + return result; 37 + 38 + result = sprintf(buf, "%s\n", (char*)path.pointer); 39 + kfree(path.pointer); 40 + return result; 41 + } 42 + 43 + struct acpi_data_node_attr { 44 + struct attribute attr; 45 + ssize_t (*show)(struct acpi_data_node *, char *); 46 + ssize_t (*store)(struct acpi_data_node *, const char *, size_t count); 47 + }; 48 + 49 + #define DATA_NODE_ATTR(_name) \ 50 + static struct acpi_data_node_attr data_node_##_name = \ 51 + __ATTR(_name, 0444, data_node_show_##_name, NULL) 52 + 53 + static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf) 54 + { 55 + return acpi_object_path(dn->handle, buf); 56 + } 57 + 58 + DATA_NODE_ATTR(path); 59 + 60 + static struct attribute *acpi_data_node_default_attrs[] = { 61 + &data_node_path.attr, 62 + NULL 63 + }; 64 + 65 + #define to_data_node(k) container_of(k, struct acpi_data_node, kobj) 66 + #define to_attr(a) container_of(a, struct acpi_data_node_attr, attr) 67 + 68 + static ssize_t acpi_data_node_attr_show(struct kobject *kobj, 69 + struct attribute *attr, char *buf) 70 + { 71 + struct acpi_data_node *dn = to_data_node(kobj); 72 + struct acpi_data_node_attr *dn_attr = to_attr(attr); 73 + 74 + return dn_attr->show ? dn_attr->show(dn, buf) : -ENXIO; 75 + } 76 + 77 + static const struct sysfs_ops acpi_data_node_sysfs_ops = { 78 + .show = acpi_data_node_attr_show, 79 + }; 80 + 81 + static void acpi_data_node_release(struct kobject *kobj) 82 + { 83 + struct acpi_data_node *dn = to_data_node(kobj); 84 + complete(&dn->kobj_done); 85 + } 86 + 87 + static struct kobj_type acpi_data_node_ktype = { 88 + .sysfs_ops = &acpi_data_node_sysfs_ops, 89 + .default_attrs = acpi_data_node_default_attrs, 90 + .release = acpi_data_node_release, 91 + }; 92 + 93 + static void acpi_expose_nondev_subnodes(struct kobject *kobj, 94 + struct acpi_device_data *data) 95 + { 96 + struct list_head *list = &data->subnodes; 97 + struct acpi_data_node *dn; 98 + 99 + if (list_empty(list)) 100 + return; 101 + 102 + list_for_each_entry(dn, list, sibling) { 103 + int ret; 104 + 105 + init_completion(&dn->kobj_done); 106 + ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype, 107 + kobj, dn->name); 108 + if (ret) 109 + acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret); 110 + else 111 + acpi_expose_nondev_subnodes(&dn->kobj, &dn->data); 112 + } 113 + } 114 + 115 + static void acpi_hide_nondev_subnodes(struct acpi_device_data *data) 116 + { 117 + struct list_head *list = &data->subnodes; 118 + struct acpi_data_node *dn; 119 + 120 + if (list_empty(list)) 121 + return; 122 + 123 + list_for_each_entry_reverse(dn, list, sibling) { 124 + acpi_hide_nondev_subnodes(&dn->data); 125 + kobject_put(&dn->kobj); 126 + } 127 + } 128 + 29 129 /** 30 130 * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent 31 131 * @acpi_dev: ACPI device object. ··· 423 323 } 424 324 static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); 425 325 426 - static ssize_t 427 - acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { 326 + static ssize_t acpi_device_path_show(struct device *dev, 327 + struct device_attribute *attr, char *buf) 328 + { 428 329 struct acpi_device *acpi_dev = to_acpi_device(dev); 429 - struct acpi_buffer path = {ACPI_ALLOCATE_BUFFER, NULL}; 430 - int result; 431 330 432 - result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); 433 - if (result) 434 - goto end; 435 - 436 - result = sprintf(buf, "%s\n", (char*)path.pointer); 437 - kfree(path.pointer); 438 - end: 439 - return result; 331 + return acpi_object_path(acpi_dev->handle, buf); 440 332 } 441 333 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); 442 334 ··· 567 475 &dev_attr_real_power_state); 568 476 } 569 477 478 + acpi_expose_nondev_subnodes(&dev->dev.kobj, &dev->data); 479 + 570 480 end: 571 481 return result; 572 482 } ··· 579 485 */ 580 486 void acpi_device_remove_files(struct acpi_device *dev) 581 487 { 488 + acpi_hide_nondev_subnodes(&dev->data); 489 + 582 490 if (dev->flags.power_manageable) { 583 491 device_remove_file(&dev->dev, &dev_attr_power_state); 584 492 if (dev->power.flags.power_resources)
+363 -74
drivers/acpi/property.c
··· 19 19 20 20 #include "internal.h" 21 21 22 + static int acpi_data_get_property_array(struct acpi_device_data *data, 23 + const char *name, 24 + acpi_object_type type, 25 + const union acpi_object **obj); 26 + 22 27 /* ACPI _DSD device properties UUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */ 23 28 static const u8 prp_uuid[16] = { 24 29 0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d, 25 30 0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01 26 31 }; 32 + /* ACPI _DSD data subnodes UUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */ 33 + static const u8 ads_uuid[16] = { 34 + 0xe6, 0xe3, 0xb8, 0xdb, 0x86, 0x58, 0xa6, 0x4b, 35 + 0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b 36 + }; 37 + 38 + static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 39 + const union acpi_object *desc, 40 + struct acpi_device_data *data); 41 + static bool acpi_extract_properties(const union acpi_object *desc, 42 + struct acpi_device_data *data); 43 + 44 + static bool acpi_nondev_subnode_ok(acpi_handle scope, 45 + const union acpi_object *link, 46 + struct list_head *list) 47 + { 48 + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 49 + struct acpi_data_node *dn; 50 + acpi_handle handle; 51 + acpi_status status; 52 + 53 + dn = kzalloc(sizeof(*dn), GFP_KERNEL); 54 + if (!dn) 55 + return false; 56 + 57 + dn->name = link->package.elements[0].string.pointer; 58 + dn->fwnode.type = FWNODE_ACPI_DATA; 59 + INIT_LIST_HEAD(&dn->data.subnodes); 60 + 61 + status = acpi_get_handle(scope, link->package.elements[1].string.pointer, 62 + &handle); 63 + if (ACPI_FAILURE(status)) 64 + goto fail; 65 + 66 + status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf, 67 + ACPI_TYPE_PACKAGE); 68 + if (ACPI_FAILURE(status)) 69 + goto fail; 70 + 71 + if (acpi_extract_properties(buf.pointer, &dn->data)) 72 + dn->handle = handle; 73 + 74 + /* 75 + * The scope for the subnode object lookup is the one of the namespace 76 + * node (device) containing the object that has returned the package. 77 + * That is, it's the scope of that object's parent. 78 + */ 79 + status = acpi_get_parent(handle, &scope); 80 + if (ACPI_SUCCESS(status) 81 + && acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data)) 82 + dn->handle = handle; 83 + 84 + if (dn->handle) { 85 + dn->data.pointer = buf.pointer; 86 + list_add_tail(&dn->sibling, list); 87 + return true; 88 + } 89 + 90 + acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n"); 91 + 92 + fail: 93 + ACPI_FREE(buf.pointer); 94 + kfree(dn); 95 + return false; 96 + } 97 + 98 + static int acpi_add_nondev_subnodes(acpi_handle scope, 99 + const union acpi_object *links, 100 + struct list_head *list) 101 + { 102 + bool ret = false; 103 + int i; 104 + 105 + for (i = 0; i < links->package.count; i++) { 106 + const union acpi_object *link; 107 + 108 + link = &links->package.elements[i]; 109 + /* Only two elements allowed, both must be strings. */ 110 + if (link->package.count == 2 111 + && link->package.elements[0].type == ACPI_TYPE_STRING 112 + && link->package.elements[1].type == ACPI_TYPE_STRING 113 + && acpi_nondev_subnode_ok(scope, link, list)) 114 + ret = true; 115 + } 116 + 117 + return ret; 118 + } 119 + 120 + static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 121 + const union acpi_object *desc, 122 + struct acpi_device_data *data) 123 + { 124 + int i; 125 + 126 + /* Look for the ACPI data subnodes UUID. */ 127 + for (i = 0; i < desc->package.count; i += 2) { 128 + const union acpi_object *uuid, *links; 129 + 130 + uuid = &desc->package.elements[i]; 131 + links = &desc->package.elements[i + 1]; 132 + 133 + /* 134 + * The first element must be a UUID and the second one must be 135 + * a package. 136 + */ 137 + if (uuid->type != ACPI_TYPE_BUFFER || uuid->buffer.length != 16 138 + || links->type != ACPI_TYPE_PACKAGE) 139 + break; 140 + 141 + if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid))) 142 + continue; 143 + 144 + return acpi_add_nondev_subnodes(scope, links, &data->subnodes); 145 + } 146 + 147 + return false; 148 + } 27 149 28 150 static bool acpi_property_value_ok(const union acpi_object *value) 29 151 { ··· 203 81 const union acpi_object *of_compatible; 204 82 int ret; 205 83 206 - ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING, 207 - &of_compatible); 84 + ret = acpi_data_get_property_array(&adev->data, "compatible", 85 + ACPI_TYPE_STRING, &of_compatible); 208 86 if (ret) { 209 87 ret = acpi_dev_get_property(adev, "compatible", 210 88 ACPI_TYPE_STRING, &of_compatible); ··· 222 100 adev->flags.of_compatible_ok = 1; 223 101 } 224 102 225 - void acpi_init_properties(struct acpi_device *adev) 103 + static bool acpi_extract_properties(const union acpi_object *desc, 104 + struct acpi_device_data *data) 226 105 { 227 - struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 228 - bool acpi_of = false; 229 - struct acpi_hardware_id *hwid; 230 - const union acpi_object *desc; 231 - acpi_status status; 232 106 int i; 233 107 234 - /* 235 - * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in 236 - * Device Tree compatible properties for this device. 237 - */ 238 - list_for_each_entry(hwid, &adev->pnp.ids, list) { 239 - if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) { 240 - acpi_of = true; 241 - break; 242 - } 243 - } 244 - 245 - status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, 246 - ACPI_TYPE_PACKAGE); 247 - if (ACPI_FAILURE(status)) 248 - goto out; 249 - 250 - desc = buf.pointer; 251 108 if (desc->package.count % 2) 252 - goto fail; 109 + return false; 253 110 254 111 /* Look for the device properties UUID. */ 255 112 for (i = 0; i < desc->package.count; i += 2) { ··· 255 154 if (!acpi_properties_format_valid(properties)) 256 155 break; 257 156 258 - adev->data.pointer = buf.pointer; 259 - adev->data.properties = properties; 260 - 261 - if (acpi_of) 262 - acpi_init_of_compatible(adev); 263 - 264 - goto out; 157 + data->properties = properties; 158 + return true; 265 159 } 266 160 267 - fail: 268 - dev_dbg(&adev->dev, "Returned _DSD data is not valid, skipping\n"); 269 - ACPI_FREE(buf.pointer); 161 + return false; 162 + } 163 + 164 + void acpi_init_properties(struct acpi_device *adev) 165 + { 166 + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 167 + struct acpi_hardware_id *hwid; 168 + acpi_status status; 169 + bool acpi_of = false; 170 + 171 + INIT_LIST_HEAD(&adev->data.subnodes); 172 + 173 + /* 174 + * Check if ACPI_DT_NAMESPACE_HID is present and inthat case we fill in 175 + * Device Tree compatible properties for this device. 176 + */ 177 + list_for_each_entry(hwid, &adev->pnp.ids, list) { 178 + if (!strcmp(hwid->id, ACPI_DT_NAMESPACE_HID)) { 179 + acpi_of = true; 180 + break; 181 + } 182 + } 183 + 184 + status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, 185 + ACPI_TYPE_PACKAGE); 186 + if (ACPI_FAILURE(status)) 187 + goto out; 188 + 189 + if (acpi_extract_properties(buf.pointer, &adev->data)) { 190 + adev->data.pointer = buf.pointer; 191 + if (acpi_of) 192 + acpi_init_of_compatible(adev); 193 + } 194 + if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data)) 195 + adev->data.pointer = buf.pointer; 196 + 197 + if (!adev->data.pointer) { 198 + acpi_handle_debug(adev->handle, "Invalid _DSD data, skipping\n"); 199 + ACPI_FREE(buf.pointer); 200 + } 270 201 271 202 out: 272 203 if (acpi_of && !adev->flags.of_compatible_ok) ··· 306 173 ACPI_DT_NAMESPACE_HID " requires 'compatible' property\n"); 307 174 } 308 175 176 + static void acpi_destroy_nondev_subnodes(struct list_head *list) 177 + { 178 + struct acpi_data_node *dn, *next; 179 + 180 + if (list_empty(list)) 181 + return; 182 + 183 + list_for_each_entry_safe_reverse(dn, next, list, sibling) { 184 + acpi_destroy_nondev_subnodes(&dn->data.subnodes); 185 + wait_for_completion(&dn->kobj_done); 186 + list_del(&dn->sibling); 187 + ACPI_FREE((void *)dn->data.pointer); 188 + kfree(dn); 189 + } 190 + } 191 + 309 192 void acpi_free_properties(struct acpi_device *adev) 310 193 { 194 + acpi_destroy_nondev_subnodes(&adev->data.subnodes); 311 195 ACPI_FREE((void *)adev->data.pointer); 312 196 adev->data.of_compatible = NULL; 313 197 adev->data.pointer = NULL; ··· 332 182 } 333 183 334 184 /** 335 - * acpi_dev_get_property - return an ACPI property with given name 336 - * @adev: ACPI device to get property 185 + * acpi_data_get_property - return an ACPI property with given name 186 + * @data: ACPI device deta object to get the property from 337 187 * @name: Name of the property 338 188 * @type: Expected property type 339 189 * @obj: Location to store the property value (if not %NULL) ··· 342 192 * object at the location pointed to by @obj if found. 343 193 * 344 194 * Callers must not attempt to free the returned objects. These objects will be 345 - * freed by the ACPI core automatically during the removal of @adev. 195 + * freed by the ACPI core automatically during the removal of @data. 346 196 * 347 197 * Return: %0 if property with @name has been found (success), 348 198 * %-EINVAL if the arguments are invalid, 349 199 * %-ENODATA if the property doesn't exist, 350 200 * %-EPROTO if the property value type doesn't match @type. 351 201 */ 352 - int acpi_dev_get_property(struct acpi_device *adev, const char *name, 353 - acpi_object_type type, const union acpi_object **obj) 202 + static int acpi_data_get_property(struct acpi_device_data *data, 203 + const char *name, acpi_object_type type, 204 + const union acpi_object **obj) 354 205 { 355 206 const union acpi_object *properties; 356 207 int i; 357 208 358 - if (!adev || !name) 209 + if (!data || !name) 359 210 return -EINVAL; 360 211 361 - if (!adev->data.pointer || !adev->data.properties) 212 + if (!data->pointer || !data->properties) 362 213 return -ENODATA; 363 214 364 - properties = adev->data.properties; 215 + properties = data->properties; 365 216 for (i = 0; i < properties->package.count; i++) { 366 217 const union acpi_object *propname, *propvalue; 367 218 const union acpi_object *property; ··· 383 232 } 384 233 return -ENODATA; 385 234 } 386 - EXPORT_SYMBOL_GPL(acpi_dev_get_property); 387 235 388 236 /** 389 - * acpi_dev_get_property_array - return an ACPI array property with given name 390 - * @adev: ACPI device to get property 237 + * acpi_dev_get_property - return an ACPI property with given name. 238 + * @adev: ACPI device to get the property from. 239 + * @name: Name of the property. 240 + * @type: Expected property type. 241 + * @obj: Location to store the property value (if not %NULL). 242 + */ 243 + int acpi_dev_get_property(struct acpi_device *adev, const char *name, 244 + acpi_object_type type, const union acpi_object **obj) 245 + { 246 + return adev ? acpi_data_get_property(&adev->data, name, type, obj) : -EINVAL; 247 + } 248 + EXPORT_SYMBOL_GPL(acpi_dev_get_property); 249 + 250 + static struct acpi_device_data *acpi_device_data_of_node(struct fwnode_handle *fwnode) 251 + { 252 + if (fwnode->type == FWNODE_ACPI) { 253 + struct acpi_device *adev = to_acpi_device_node(fwnode); 254 + return &adev->data; 255 + } else if (fwnode->type == FWNODE_ACPI_DATA) { 256 + struct acpi_data_node *dn = to_acpi_data_node(fwnode); 257 + return &dn->data; 258 + } 259 + return NULL; 260 + } 261 + 262 + /** 263 + * acpi_node_prop_get - return an ACPI property with given name. 264 + * @fwnode: Firmware node to get the property from. 265 + * @propname: Name of the property. 266 + * @valptr: Location to store a pointer to the property value (if not %NULL). 267 + */ 268 + int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, 269 + void **valptr) 270 + { 271 + return acpi_data_get_property(acpi_device_data_of_node(fwnode), 272 + propname, ACPI_TYPE_ANY, 273 + (const union acpi_object **)valptr); 274 + } 275 + 276 + /** 277 + * acpi_data_get_property_array - return an ACPI array property with given name 278 + * @adev: ACPI data object to get the property from 391 279 * @name: Name of the property 392 280 * @type: Expected type of array elements 393 281 * @obj: Location to store a pointer to the property value (if not NULL) ··· 435 245 * ACPI object at the location pointed to by @obj if found. 436 246 * 437 247 * Callers must not attempt to free the returned objects. Those objects will be 438 - * freed by the ACPI core automatically during the removal of @adev. 248 + * freed by the ACPI core automatically during the removal of @data. 439 249 * 440 250 * Return: %0 if array property (package) with @name has been found (success), 441 251 * %-EINVAL if the arguments are invalid, ··· 443 253 * %-EPROTO if the property is not a package or the type of its elements 444 254 * doesn't match @type. 445 255 */ 446 - int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, 447 - acpi_object_type type, 448 - const union acpi_object **obj) 256 + static int acpi_data_get_property_array(struct acpi_device_data *data, 257 + const char *name, 258 + acpi_object_type type, 259 + const union acpi_object **obj) 449 260 { 450 261 const union acpi_object *prop; 451 262 int ret, i; 452 263 453 - ret = acpi_dev_get_property(adev, name, ACPI_TYPE_PACKAGE, &prop); 264 + ret = acpi_data_get_property(data, name, ACPI_TYPE_PACKAGE, &prop); 454 265 if (ret) 455 266 return ret; 456 267 ··· 466 275 467 276 return 0; 468 277 } 469 - EXPORT_SYMBOL_GPL(acpi_dev_get_property_array); 470 278 471 279 /** 472 - * acpi_dev_get_property_reference - returns handle to the referenced object 473 - * @adev: ACPI device to get property 474 - * @name: Name of the property 280 + * acpi_data_get_property_reference - returns handle to the referenced object 281 + * @data: ACPI device data object containing the property 282 + * @propname: Name of the property 475 283 * @index: Index of the reference to return 476 284 * @args: Location to store the returned reference with optional arguments 477 285 * ··· 484 294 * 485 295 * Return: %0 on success, negative error code on failure. 486 296 */ 487 - int acpi_dev_get_property_reference(struct acpi_device *adev, 488 - const char *name, size_t index, 489 - struct acpi_reference_args *args) 297 + static int acpi_data_get_property_reference(struct acpi_device_data *data, 298 + const char *propname, size_t index, 299 + struct acpi_reference_args *args) 490 300 { 491 301 const union acpi_object *element, *end; 492 302 const union acpi_object *obj; 493 303 struct acpi_device *device; 494 304 int ret, idx = 0; 495 305 496 - ret = acpi_dev_get_property(adev, name, ACPI_TYPE_ANY, &obj); 306 + ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); 497 307 if (ret) 498 308 return ret; 499 309 ··· 568 378 569 379 return -EPROTO; 570 380 } 571 - EXPORT_SYMBOL_GPL(acpi_dev_get_property_reference); 572 381 573 - int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, 574 - void **valptr) 382 + /** 383 + * acpi_node_get_property_reference - get a handle to the referenced object. 384 + * @fwnode: Firmware node to get the property from. 385 + * @propname: Name of the property. 386 + * @index: Index of the reference to return. 387 + * @args: Location to store the returned reference with optional arguments. 388 + */ 389 + int acpi_node_get_property_reference(struct fwnode_handle *fwnode, 390 + const char *name, size_t index, 391 + struct acpi_reference_args *args) 575 392 { 576 - return acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, 577 - (const union acpi_object **)valptr); 578 - } 393 + struct acpi_device_data *data = acpi_device_data_of_node(fwnode); 579 394 580 - int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 581 - enum dev_prop_type proptype, void *val) 395 + return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL; 396 + } 397 + EXPORT_SYMBOL_GPL(acpi_node_get_property_reference); 398 + 399 + static int acpi_data_prop_read_single(struct acpi_device_data *data, 400 + const char *propname, 401 + enum dev_prop_type proptype, void *val) 582 402 { 583 403 const union acpi_object *obj; 584 404 int ret; ··· 597 397 return -EINVAL; 598 398 599 399 if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { 600 - ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_INTEGER, &obj); 400 + ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj); 601 401 if (ret) 602 402 return ret; 603 403 ··· 622 422 break; 623 423 } 624 424 } else if (proptype == DEV_PROP_STRING) { 625 - ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_STRING, &obj); 425 + ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj); 626 426 if (ret) 627 427 return ret; 628 428 ··· 631 431 ret = -EINVAL; 632 432 } 633 433 return ret; 434 + } 435 + 436 + int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 437 + enum dev_prop_type proptype, void *val) 438 + { 439 + return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL; 634 440 } 635 441 636 442 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, ··· 715 509 return 0; 716 510 } 717 511 718 - int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 719 - enum dev_prop_type proptype, void *val, size_t nval) 512 + static int acpi_data_prop_read(struct acpi_device_data *data, 513 + const char *propname, 514 + enum dev_prop_type proptype, 515 + void *val, size_t nval) 720 516 { 721 517 const union acpi_object *obj; 722 518 const union acpi_object *items; 723 519 int ret; 724 520 725 521 if (val && nval == 1) { 726 - ret = acpi_dev_prop_read_single(adev, propname, proptype, val); 522 + ret = acpi_data_prop_read_single(data, propname, proptype, val); 727 523 if (!ret) 728 524 return ret; 729 525 } 730 526 731 - ret = acpi_dev_get_property_array(adev, propname, ACPI_TYPE_ANY, &obj); 527 + ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj); 732 528 if (ret) 733 529 return ret; 734 530 ··· 765 557 break; 766 558 } 767 559 return ret; 560 + } 561 + 562 + int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 563 + enum dev_prop_type proptype, void *val, size_t nval) 564 + { 565 + return adev ? acpi_data_prop_read(&adev->data, propname, proptype, val, nval) : -EINVAL; 566 + } 567 + 568 + /** 569 + * acpi_node_prop_read - retrieve the value of an ACPI property with given name. 570 + * @fwnode: Firmware node to get the property from. 571 + * @propname: Name of the property. 572 + * @proptype: Expected property type. 573 + * @val: Location to store the property value (if not %NULL). 574 + * @nval: Size of the array pointed to by @val. 575 + * 576 + * If @val is %NULL, return the number of array elements comprising the value 577 + * of the property. Otherwise, read at most @nval values to the array at the 578 + * location pointed to by @val. 579 + */ 580 + int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, 581 + enum dev_prop_type proptype, void *val, size_t nval) 582 + { 583 + return acpi_data_prop_read(acpi_device_data_of_node(fwnode), 584 + propname, proptype, val, nval); 585 + } 586 + 587 + /** 588 + * acpi_get_next_subnode - Return the next child node handle for a device. 589 + * @dev: Device to find the next child node for. 590 + * @child: Handle to one of the device's child nodes or a null handle. 591 + */ 592 + struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 593 + struct fwnode_handle *child) 594 + { 595 + struct acpi_device *adev = ACPI_COMPANION(dev); 596 + struct list_head *head, *next; 597 + 598 + if (!adev) 599 + return NULL; 600 + 601 + if (!child || child->type == FWNODE_ACPI) { 602 + head = &adev->children; 603 + if (list_empty(head)) 604 + goto nondev; 605 + 606 + if (child) { 607 + adev = to_acpi_device_node(child); 608 + next = adev->node.next; 609 + if (next == head) { 610 + child = NULL; 611 + goto nondev; 612 + } 613 + adev = list_entry(next, struct acpi_device, node); 614 + } else { 615 + adev = list_first_entry(head, struct acpi_device, node); 616 + } 617 + return acpi_fwnode_handle(adev); 618 + } 619 + 620 + nondev: 621 + if (!child || child->type == FWNODE_ACPI_DATA) { 622 + struct acpi_data_node *dn; 623 + 624 + head = &adev->data.subnodes; 625 + if (list_empty(head)) 626 + return NULL; 627 + 628 + if (child) { 629 + dn = to_acpi_data_node(child); 630 + next = dn->sibling.next; 631 + if (next == head) 632 + return NULL; 633 + 634 + dn = list_entry(next, struct acpi_data_node, sibling); 635 + } else { 636 + dn = list_first_entry(head, struct acpi_data_node, sibling); 637 + } 638 + return &dn->fwnode; 639 + } 640 + return NULL; 768 641 }
-20
drivers/acpi/scan.c
··· 695 695 return result; 696 696 } 697 697 698 - struct acpi_device *acpi_get_next_child(struct device *dev, 699 - struct acpi_device *child) 700 - { 701 - struct acpi_device *adev = ACPI_COMPANION(dev); 702 - struct list_head *head, *next; 703 - 704 - if (!adev) 705 - return NULL; 706 - 707 - head = &adev->children; 708 - if (list_empty(head)) 709 - return NULL; 710 - 711 - if (!child) 712 - return list_first_entry(head, struct acpi_device, node); 713 - 714 - next = child->node.next; 715 - return next == head ? NULL : list_entry(next, struct acpi_device, node); 716 - } 717 - 718 698 /* -------------------------------------------------------------------------- 719 699 Device Enumeration 720 700 -------------------------------------------------------------------------- */
+76 -12
drivers/base/property.c
··· 134 134 if (is_of_node(fwnode)) 135 135 return of_property_read_bool(to_of_node(fwnode), propname); 136 136 else if (is_acpi_node(fwnode)) 137 - return !acpi_dev_prop_get(to_acpi_node(fwnode), propname, NULL); 137 + return !acpi_node_prop_get(fwnode, propname, NULL); 138 138 139 139 return !!pset_prop_get(to_pset(fwnode), propname); 140 140 } ··· 287 287 } 288 288 EXPORT_SYMBOL_GPL(device_property_read_string); 289 289 290 + /** 291 + * device_property_match_string - find a string in an array and return index 292 + * @dev: Device to get the property of 293 + * @propname: Name of the property holding the array 294 + * @string: String to look for 295 + * 296 + * Find a given string in a string array and if it is found return the 297 + * index back. 298 + * 299 + * Return: %0 if the property was found (success), 300 + * %-EINVAL if given arguments are not valid, 301 + * %-ENODATA if the property does not have a value, 302 + * %-EPROTO if the property is not an array of strings, 303 + * %-ENXIO if no suitable firmware interface is present. 304 + */ 305 + int device_property_match_string(struct device *dev, const char *propname, 306 + const char *string) 307 + { 308 + return fwnode_property_match_string(dev_fwnode(dev), propname, string); 309 + } 310 + EXPORT_SYMBOL_GPL(device_property_match_string); 311 + 290 312 #define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval) \ 291 313 (val) ? of_property_read_##type##_array((node), (propname), (val), (nval)) \ 292 314 : of_property_count_elems_of_size((node), (propname), sizeof(type)) ··· 320 298 _ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_, \ 321 299 _type_, _val_, _nval_); \ 322 300 else if (is_acpi_node(_fwnode_)) \ 323 - _ret_ = acpi_dev_prop_read(to_acpi_node(_fwnode_), _propname_, \ 324 - _proptype_, _val_, _nval_); \ 301 + _ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_, \ 302 + _val_, _nval_); \ 325 303 else if (is_pset(_fwnode_)) \ 326 304 _ret_ = pset_prop_read_array(to_pset(_fwnode_), _propname_, \ 327 305 _proptype_, _val_, _nval_); \ ··· 462 440 propname, val, nval) : 463 441 of_property_count_strings(to_of_node(fwnode), propname); 464 442 else if (is_acpi_node(fwnode)) 465 - return acpi_dev_prop_read(to_acpi_node(fwnode), propname, 466 - DEV_PROP_STRING, val, nval); 443 + return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, 444 + val, nval); 467 445 else if (is_pset(fwnode)) 468 446 return pset_prop_read_array(to_pset(fwnode), propname, 469 447 DEV_PROP_STRING, val, nval); ··· 492 470 if (is_of_node(fwnode)) 493 471 return of_property_read_string(to_of_node(fwnode), propname, val); 494 472 else if (is_acpi_node(fwnode)) 495 - return acpi_dev_prop_read(to_acpi_node(fwnode), propname, 496 - DEV_PROP_STRING, val, 1); 473 + return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, 474 + val, 1); 497 475 498 476 return pset_prop_read_array(to_pset(fwnode), propname, 499 477 DEV_PROP_STRING, val, 1); 500 478 } 501 479 EXPORT_SYMBOL_GPL(fwnode_property_read_string); 480 + 481 + /** 482 + * fwnode_property_match_string - find a string in an array and return index 483 + * @fwnode: Firmware node to get the property of 484 + * @propname: Name of the property holding the array 485 + * @string: String to look for 486 + * 487 + * Find a given string in a string array and if it is found return the 488 + * index back. 489 + * 490 + * Return: %0 if the property was found (success), 491 + * %-EINVAL if given arguments are not valid, 492 + * %-ENODATA if the property does not have a value, 493 + * %-EPROTO if the property is not an array of strings, 494 + * %-ENXIO if no suitable firmware interface is present. 495 + */ 496 + int fwnode_property_match_string(struct fwnode_handle *fwnode, 497 + const char *propname, const char *string) 498 + { 499 + const char **values; 500 + int nval, ret, i; 501 + 502 + nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0); 503 + if (nval < 0) 504 + return nval; 505 + 506 + values = kcalloc(nval, sizeof(*values), GFP_KERNEL); 507 + if (!values) 508 + return -ENOMEM; 509 + 510 + ret = fwnode_property_read_string_array(fwnode, propname, values, nval); 511 + if (ret < 0) 512 + goto out; 513 + 514 + ret = -ENODATA; 515 + for (i = 0; i < nval; i++) { 516 + if (!strcmp(values[i], string)) { 517 + ret = i; 518 + break; 519 + } 520 + } 521 + out: 522 + kfree(values); 523 + return ret; 524 + } 525 + EXPORT_SYMBOL_GPL(fwnode_property_match_string); 502 526 503 527 /** 504 528 * device_get_next_child_node - Return the next child node handle for a device ··· 561 493 if (node) 562 494 return &node->fwnode; 563 495 } else if (IS_ENABLED(CONFIG_ACPI)) { 564 - struct acpi_device *node; 565 - 566 - node = acpi_get_next_child(dev, to_acpi_node(child)); 567 - if (node) 568 - return acpi_fwnode_handle(node); 496 + return acpi_get_next_subnode(dev, child); 569 497 } 570 498 return NULL; 571 499 }
+16 -7
drivers/dma/acpi-dma.c
··· 21 21 #include <linux/ioport.h> 22 22 #include <linux/acpi.h> 23 23 #include <linux/acpi_dma.h> 24 + #include <linux/property.h> 24 25 25 26 static LIST_HEAD(acpi_dma_list); 26 27 static DEFINE_MUTEX(acpi_dma_lock); ··· 414 413 * translate the names "tx" and "rx" here based on the most common case where 415 414 * the first FixedDMA descriptor is TX and second is RX. 416 415 * 416 + * If the device has "dma-names" property the FixedDMA descriptor indices 417 + * are retrieved based on those. Otherwise the function falls back using 418 + * hardcoded indices. 419 + * 417 420 * Return: 418 421 * Pointer to appropriate dma channel on success or an error pointer. 419 422 */ 420 423 struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev, 421 424 const char *name) 422 425 { 423 - size_t index; 426 + int index; 424 427 425 - if (!strcmp(name, "tx")) 426 - index = 0; 427 - else if (!strcmp(name, "rx")) 428 - index = 1; 429 - else 430 - return ERR_PTR(-ENODEV); 428 + index = device_property_match_string(dev, "dma-names", name); 429 + if (index < 0) { 430 + if (!strcmp(name, "tx")) 431 + index = 0; 432 + else if (!strcmp(name, "rx")) 433 + index = 1; 434 + else 435 + return ERR_PTR(-ENODEV); 436 + } 431 437 438 + dev_dbg(dev, "found DMA channel \"%s\" at index %d\n", name, index); 432 439 return acpi_dma_request_slave_chan_by_index(dev, index); 433 440 } 434 441 EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name);
+110 -45
drivers/gpio/gpiolib-acpi.c
··· 389 389 struct acpi_gpio_info info; 390 390 int index; 391 391 int pin_index; 392 + bool active_low; 393 + struct acpi_device *adev; 392 394 struct gpio_desc *desc; 393 395 int n; 394 396 }; ··· 427 425 return 1; 428 426 } 429 427 428 + static int acpi_gpio_resource_lookup(struct acpi_gpio_lookup *lookup, 429 + struct acpi_gpio_info *info) 430 + { 431 + struct list_head res_list; 432 + int ret; 433 + 434 + INIT_LIST_HEAD(&res_list); 435 + 436 + ret = acpi_dev_get_resources(lookup->adev, &res_list, acpi_find_gpio, 437 + lookup); 438 + if (ret < 0) 439 + return ret; 440 + 441 + acpi_dev_free_resource_list(&res_list); 442 + 443 + if (!lookup->desc) 444 + return -ENOENT; 445 + 446 + if (info) { 447 + *info = lookup->info; 448 + if (lookup->active_low) 449 + info->active_low = lookup->active_low; 450 + } 451 + return 0; 452 + } 453 + 454 + static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, 455 + const char *propname, int index, 456 + struct acpi_gpio_lookup *lookup) 457 + { 458 + struct acpi_reference_args args; 459 + int ret; 460 + 461 + memset(&args, 0, sizeof(args)); 462 + ret = acpi_node_get_property_reference(fwnode, propname, index, &args); 463 + if (ret) { 464 + struct acpi_device *adev = to_acpi_device_node(fwnode); 465 + 466 + if (!adev) 467 + return ret; 468 + 469 + if (!acpi_get_driver_gpio_data(adev, propname, index, &args)) 470 + return ret; 471 + } 472 + /* 473 + * The property was found and resolved, so need to lookup the GPIO based 474 + * on returned args. 475 + */ 476 + lookup->adev = args.adev; 477 + if (args.nargs >= 2) { 478 + lookup->index = args.args[0]; 479 + lookup->pin_index = args.args[1]; 480 + /* 3rd argument, if present is used to specify active_low. */ 481 + if (args.nargs >= 3) 482 + lookup->active_low = !!args.args[2]; 483 + } 484 + return 0; 485 + } 486 + 430 487 /** 431 488 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources 432 489 * @adev: pointer to a ACPI device to get GPIO from ··· 513 452 struct acpi_gpio_info *info) 514 453 { 515 454 struct acpi_gpio_lookup lookup; 516 - struct list_head resource_list; 517 - bool active_low = false; 518 455 int ret; 519 456 520 457 if (!adev) ··· 522 463 lookup.index = index; 523 464 524 465 if (propname) { 525 - struct acpi_reference_args args; 526 - 527 466 dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname); 528 467 529 - memset(&args, 0, sizeof(args)); 530 - ret = acpi_dev_get_property_reference(adev, propname, 531 - index, &args); 532 - if (ret) { 533 - bool found = acpi_get_driver_gpio_data(adev, propname, 534 - index, &args); 535 - if (!found) 536 - return ERR_PTR(ret); 537 - } 468 + ret = acpi_gpio_property_lookup(acpi_fwnode_handle(adev), 469 + propname, index, &lookup); 470 + if (ret) 471 + return ERR_PTR(ret); 538 472 539 - /* 540 - * The property was found and resolved so need to 541 - * lookup the GPIO based on returned args instead. 542 - */ 543 - adev = args.adev; 544 - if (args.nargs >= 2) { 545 - lookup.index = args.args[0]; 546 - lookup.pin_index = args.args[1]; 547 - /* 548 - * 3rd argument, if present is used to 549 - * specify active_low. 550 - */ 551 - if (args.nargs >= 3) 552 - active_low = !!args.args[2]; 553 - } 554 - 555 - dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n", 556 - dev_name(&adev->dev), args.nargs, 557 - args.args[0], args.args[1], args.args[2]); 473 + dev_dbg(&adev->dev, "GPIO: _DSD returned %s %d %d %u\n", 474 + dev_name(&lookup.adev->dev), lookup.index, 475 + lookup.pin_index, lookup.active_low); 558 476 } else { 559 477 dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index); 478 + lookup.adev = adev; 560 479 } 561 480 562 - INIT_LIST_HEAD(&resource_list); 563 - ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio, 564 - &lookup); 565 - if (ret < 0) 481 + ret = acpi_gpio_resource_lookup(&lookup, info); 482 + return ret ? ERR_PTR(ret) : lookup.desc; 483 + } 484 + 485 + /** 486 + * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources 487 + * @fwnode: pointer to an ACPI firmware node to get the GPIO information from 488 + * @propname: Property name of the GPIO 489 + * @index: index of GpioIo/GpioInt resource (starting from %0) 490 + * @info: info pointer to fill in (optional) 491 + * 492 + * If @fwnode is an ACPI device object, call %acpi_get_gpiod_by_index() for it. 493 + * Otherwise (ie. it is a data-only non-device object), use the property-based 494 + * GPIO lookup to get to the GPIO resource with the relevant information and use 495 + * that to obtain the GPIO descriptor to return. 496 + */ 497 + struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, 498 + const char *propname, int index, 499 + struct acpi_gpio_info *info) 500 + { 501 + struct acpi_gpio_lookup lookup; 502 + struct acpi_device *adev; 503 + int ret; 504 + 505 + adev = to_acpi_device_node(fwnode); 506 + if (adev) 507 + return acpi_get_gpiod_by_index(adev, propname, index, info); 508 + 509 + if (!is_acpi_data_node(fwnode)) 510 + return ERR_PTR(-ENODEV); 511 + 512 + if (!propname) 513 + return ERR_PTR(-EINVAL); 514 + 515 + memset(&lookup, 0, sizeof(lookup)); 516 + lookup.index = index; 517 + 518 + ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); 519 + if (ret) 566 520 return ERR_PTR(ret); 567 521 568 - acpi_dev_free_resource_list(&resource_list); 569 - 570 - if (lookup.desc && info) { 571 - *info = lookup.info; 572 - if (active_low) 573 - info->active_low = active_low; 574 - } 575 - 576 - return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT); 522 + ret = acpi_gpio_resource_lookup(&lookup, info); 523 + return ret ? ERR_PTR(ret) : lookup.desc; 577 524 } 578 525 579 526 /**
+1 -2
drivers/gpio/gpiolib.c
··· 2093 2093 } else if (is_acpi_node(fwnode)) { 2094 2094 struct acpi_gpio_info info; 2095 2095 2096 - desc = acpi_get_gpiod_by_index(to_acpi_node(fwnode), propname, 0, 2097 - &info); 2096 + desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); 2098 2097 if (!IS_ERR(desc)) 2099 2098 active_low = info.active_low; 2100 2099 }
+9 -1
drivers/gpio/gpiolib.h
··· 42 42 struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, 43 43 const char *propname, int index, 44 44 struct acpi_gpio_info *info); 45 + struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, 46 + const char *propname, int index, 47 + struct acpi_gpio_info *info); 45 48 46 49 int acpi_gpio_count(struct device *dev, const char *con_id); 47 50 #else ··· 63 60 { 64 61 return ERR_PTR(-ENOSYS); 65 62 } 66 - 63 + static inline struct gpio_desc * 64 + acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, 65 + int index, struct acpi_gpio_info *info) 66 + { 67 + return ERR_PTR(-ENXIO); 68 + } 67 69 static inline int acpi_gpio_count(struct device *dev, const char *con_id) 68 70 { 69 71 return -ENODEV;
+31 -2
include/acpi/acpi_bus.h
··· 343 343 const union acpi_object *pointer; 344 344 const union acpi_object *properties; 345 345 const union acpi_object *of_compatible; 346 + struct list_head subnodes; 346 347 }; 347 348 348 349 struct acpi_gpio_mapping; ··· 377 376 struct list_head physical_node_list; 378 377 struct mutex physical_node_lock; 379 378 void (*remove)(struct acpi_device *); 379 + }; 380 + 381 + /* Non-device subnode */ 382 + struct acpi_data_node { 383 + const char *name; 384 + acpi_handle handle; 385 + struct fwnode_handle fwnode; 386 + struct acpi_device_data data; 387 + struct list_head sibling; 388 + struct kobject kobj; 389 + struct completion kobj_done; 380 390 }; 381 391 382 392 static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent) ··· 425 413 426 414 static inline bool is_acpi_node(struct fwnode_handle *fwnode) 427 415 { 416 + return fwnode && (fwnode->type == FWNODE_ACPI 417 + || fwnode->type == FWNODE_ACPI_DATA); 418 + } 419 + 420 + static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) 421 + { 428 422 return fwnode && fwnode->type == FWNODE_ACPI; 429 423 } 430 424 431 - static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode) 425 + static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) 432 426 { 433 - return is_acpi_node(fwnode) ? 427 + return is_acpi_device_node(fwnode) ? 434 428 container_of(fwnode, struct acpi_device, fwnode) : NULL; 429 + } 430 + 431 + static inline bool is_acpi_data_node(struct fwnode_handle *fwnode) 432 + { 433 + return fwnode && fwnode->type == FWNODE_ACPI_DATA; 434 + } 435 + 436 + static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode) 437 + { 438 + return is_acpi_data_node(fwnode) ? 439 + container_of(fwnode, struct acpi_data_node, fwnode) : NULL; 435 440 } 436 441 437 442 static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
+45 -23
include/linux/acpi.h
··· 49 49 return adev ? adev->handle : NULL; 50 50 } 51 51 52 - #define ACPI_COMPANION(dev) to_acpi_node((dev)->fwnode) 52 + #define ACPI_COMPANION(dev) to_acpi_device_node((dev)->fwnode) 53 53 #define ACPI_COMPANION_SET(dev, adev) set_primary_fwnode(dev, (adev) ? \ 54 54 acpi_fwnode_handle(adev) : NULL) 55 55 #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) ··· 69 69 70 70 static inline bool has_acpi_companion(struct device *dev) 71 71 { 72 - return is_acpi_node(dev->fwnode); 72 + return is_acpi_device_node(dev->fwnode); 73 73 } 74 74 75 75 static inline void acpi_preset_companion(struct device *dev, ··· 462 462 return false; 463 463 } 464 464 465 - static inline struct acpi_device *to_acpi_node(struct fwnode_handle *fwnode) 465 + static inline bool is_acpi_device_node(struct fwnode_handle *fwnode) 466 + { 467 + return false; 468 + } 469 + 470 + static inline struct acpi_device *to_acpi_device_node(struct fwnode_handle *fwnode) 471 + { 472 + return NULL; 473 + } 474 + 475 + static inline bool is_acpi_data_node(struct fwnode_handle *fwnode) 476 + { 477 + return false; 478 + } 479 + 480 + static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwnode) 466 481 { 467 482 return NULL; 468 483 } ··· 759 744 #ifdef CONFIG_ACPI 760 745 int acpi_dev_get_property(struct acpi_device *adev, const char *name, 761 746 acpi_object_type type, const union acpi_object **obj); 762 - int acpi_dev_get_property_array(struct acpi_device *adev, const char *name, 763 - acpi_object_type type, 764 - const union acpi_object **obj); 765 - int acpi_dev_get_property_reference(struct acpi_device *adev, 766 - const char *name, size_t index, 767 - struct acpi_reference_args *args); 747 + int acpi_node_get_property_reference(struct fwnode_handle *fwnode, 748 + const char *name, size_t index, 749 + struct acpi_reference_args *args); 768 750 769 - int acpi_dev_prop_get(struct acpi_device *adev, const char *propname, 770 - void **valptr); 751 + int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, 752 + void **valptr); 771 753 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 772 754 enum dev_prop_type proptype, void *val); 755 + int acpi_node_prop_read(struct fwnode_handle *fwnode, const char *propname, 756 + enum dev_prop_type proptype, void *val, size_t nval); 773 757 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 774 758 enum dev_prop_type proptype, void *val, size_t nval); 775 759 776 - struct acpi_device *acpi_get_next_child(struct device *dev, 777 - struct acpi_device *child); 760 + struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 761 + struct fwnode_handle *subnode); 778 762 #else 779 763 static inline int acpi_dev_get_property(struct acpi_device *adev, 780 764 const char *name, acpi_object_type type, ··· 781 767 { 782 768 return -ENXIO; 783 769 } 784 - static inline int acpi_dev_get_property_array(struct acpi_device *adev, 785 - const char *name, 786 - acpi_object_type type, 787 - const union acpi_object **obj) 770 + 771 + static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, 772 + const char *name, const char *cells_name, 773 + size_t index, struct acpi_reference_args *args) 788 774 { 789 775 return -ENXIO; 790 776 } 791 - static inline int acpi_dev_get_property_reference(struct acpi_device *adev, 792 - const char *name, const char *cells_name, 793 - size_t index, struct acpi_reference_args *args) 777 + 778 + static inline int acpi_node_prop_get(struct fwnode_handle *fwnode, 779 + const char *propname, 780 + void **valptr) 794 781 { 795 782 return -ENXIO; 796 783 } ··· 811 796 return -ENXIO; 812 797 } 813 798 799 + static inline int acpi_node_prop_read(struct fwnode_handle *fwnode, 800 + const char *propname, 801 + enum dev_prop_type proptype, 802 + void *val, size_t nval) 803 + { 804 + return -ENXIO; 805 + } 806 + 814 807 static inline int acpi_dev_prop_read(struct acpi_device *adev, 815 808 const char *propname, 816 809 enum dev_prop_type proptype, ··· 827 804 return -ENXIO; 828 805 } 829 806 830 - static inline struct acpi_device *acpi_get_next_child(struct device *dev, 831 - struct acpi_device *child) 807 + static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 808 + struct fwnode_handle *subnode) 832 809 { 833 810 return NULL; 834 811 } 835 - 836 812 #endif 837 813 838 814 #endif /*_LINUX_ACPI_H*/
+1
include/linux/fwnode.h
··· 16 16 FWNODE_INVALID = 0, 17 17 FWNODE_OF, 18 18 FWNODE_ACPI, 19 + FWNODE_ACPI_DATA, 19 20 FWNODE_PDATA, 20 21 }; 21 22
+4
include/linux/property.h
··· 40 40 const char **val, size_t nval); 41 41 int device_property_read_string(struct device *dev, const char *propname, 42 42 const char **val); 43 + int device_property_match_string(struct device *dev, 44 + const char *propname, const char *string); 43 45 44 46 bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); 45 47 int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, ··· 61 59 size_t nval); 62 60 int fwnode_property_read_string(struct fwnode_handle *fwnode, 63 61 const char *propname, const char **val); 62 + int fwnode_property_match_string(struct fwnode_handle *fwnode, 63 + const char *propname, const char *string); 64 64 65 65 struct fwnode_handle *device_get_next_child_node(struct device *dev, 66 66 struct fwnode_handle *child);