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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'devprop-4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull device properties framework fixes from Rafael Wysocki:
"These fix an issue related to device removal introduced during the 4.9
cycle and fix up new functionality added recently.

Specifics:

- Fix a device properties management issue, introduced during the 4.9
cycle, that causes device properties associated with a parent
device to go away on a removal of its child in some cases (Jarkko
Nikula).

- Fix inconsistencies in error codes returned by a new function
helper in the device properties framework depending on the
underlying low-level firmware interface, DT or ACPI, by making the
meaning of error codes returned in the ACPI case agree with the
meaning of DT error codes in analogous situations (Sakari Ailus)"

* tag 'devprop-4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI: properties: Fix __acpi_node_get_property_reference() return codes
ACPI: properties: Align return codes of __acpi_node_get_property_reference()
device property: Track owner device of device property

+28 -20
+15 -14
drivers/acpi/property.c
··· 571 571 * } 572 572 * } 573 573 * 574 - * Calling this function with index %2 return %-ENOENT and with index %3 575 - * returns the last entry. If the property does not contain any more values 576 - * %-ENODATA is returned. The NULL entry must be single integer and 577 - * preferably contain value %0. 574 + * Calling this function with index %2 or index %3 return %-ENOENT. If the 575 + * property does not contain any more values %-ENOENT is returned. The NULL 576 + * entry must be single integer and preferably contain value %0. 578 577 * 579 578 * Return: %0 on success, negative error code on failure. 580 579 */ ··· 589 590 590 591 data = acpi_device_data_of_node(fwnode); 591 592 if (!data) 592 - return -EINVAL; 593 + return -ENOENT; 593 594 594 595 ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); 595 596 if (ret) 596 - return ret; 597 + return ret == -EINVAL ? -ENOENT : -EINVAL; 597 598 598 599 /* 599 600 * The simplest case is when the value is a single reference. Just ··· 605 606 606 607 ret = acpi_bus_get_device(obj->reference.handle, &device); 607 608 if (ret) 608 - return ret; 609 + return ret == -ENODEV ? -EINVAL : ret; 609 610 610 611 args->adev = device; 611 612 args->nargs = 0; ··· 621 622 * The index argument is then used to determine which reference 622 623 * the caller wants (along with the arguments). 623 624 */ 624 - if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count) 625 - return -EPROTO; 625 + if (obj->type != ACPI_TYPE_PACKAGE) 626 + return -EINVAL; 627 + if (index >= obj->package.count) 628 + return -ENOENT; 626 629 627 630 element = obj->package.elements; 628 631 end = element + obj->package.count; ··· 636 635 ret = acpi_bus_get_device(element->reference.handle, 637 636 &device); 638 637 if (ret) 639 - return -ENODEV; 638 + return -EINVAL; 640 639 641 640 nargs = 0; 642 641 element++; ··· 650 649 else if (type == ACPI_TYPE_LOCAL_REFERENCE) 651 650 break; 652 651 else 653 - return -EPROTO; 652 + return -EINVAL; 654 653 } 655 654 656 655 if (nargs > MAX_ACPI_REFERENCE_ARGS) 657 - return -EPROTO; 656 + return -EINVAL; 658 657 659 658 if (idx == index) { 660 659 args->adev = device; ··· 671 670 return -ENOENT; 672 671 element++; 673 672 } else { 674 - return -EPROTO; 673 + return -EINVAL; 675 674 } 676 675 677 676 idx++; 678 677 } 679 678 680 - return -ENODATA; 679 + return -ENOENT; 681 680 } 682 681 EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); 683 682
+13 -6
drivers/base/property.c
··· 21 21 #include <linux/phy.h> 22 22 23 23 struct property_set { 24 + struct device *dev; 24 25 struct fwnode_handle fwnode; 25 26 const struct property_entry *properties; 26 27 }; ··· 683 682 * Caller is responsible to call fwnode_handle_put() on the returned 684 683 * args->fwnode pointer. 685 684 * 685 + * Returns: %0 on success 686 + * %-ENOENT when the index is out of bounds, the index has an empty 687 + * reference or the property was not found 688 + * %-EINVAL on parse error 686 689 */ 687 690 int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, 688 691 const char *prop, const char *nargs_prop, ··· 896 891 void device_remove_properties(struct device *dev) 897 892 { 898 893 struct fwnode_handle *fwnode; 894 + struct property_set *pset; 899 895 900 896 fwnode = dev_fwnode(dev); 901 897 if (!fwnode) ··· 906 900 * the pset. If there is no real firmware node (ACPI/DT) primary 907 901 * will hold the pset. 908 902 */ 909 - if (is_pset_node(fwnode)) { 903 + pset = to_pset_node(fwnode); 904 + if (pset) { 910 905 set_primary_fwnode(dev, NULL); 911 - pset_free_set(to_pset_node(fwnode)); 912 906 } else { 913 - fwnode = fwnode->secondary; 914 - if (!IS_ERR(fwnode) && is_pset_node(fwnode)) { 907 + pset = to_pset_node(fwnode->secondary); 908 + if (pset && dev == pset->dev) 915 909 set_secondary_fwnode(dev, NULL); 916 - pset_free_set(to_pset_node(fwnode)); 917 - } 918 910 } 911 + if (pset && dev == pset->dev) 912 + pset_free_set(pset); 919 913 } 920 914 EXPORT_SYMBOL_GPL(device_remove_properties); 921 915 ··· 944 938 945 939 p->fwnode.ops = &pset_fwnode_ops; 946 940 set_secondary_fwnode(dev, &p->fwnode); 941 + p->dev = dev; 947 942 return 0; 948 943 } 949 944 EXPORT_SYMBOL_GPL(device_add_properties);