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

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

Pull generic device properties framework updates from Rafael Wysocki:
"These add support for the ports and endpoints concepts, based on the
existing DT support for them, to the generic device properties
framework and update the ACPI _DSD properties code to recognize ports
and endpoints accordingly.

Specifics:

- Extend the ACPI _DSD properties code and the generic device
properties framework to support the concept of remote endponts
(Mika Westerberg, Sakari Ailus).

- Document the support for ports and endpoints in _DSD properties and
extend the generic device properties framework to make it more
suitable for the handling of ports and endpoints (Sakari Ailus)"

* tag 'devprop-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
device property: Read strings using string array reading functions
device property: fwnode_property_read_string_array() returns nr of strings
device property: Fix reading pset strings using array access functions
device property: fwnode_property_read_string_array() may return -EILSEQ
ACPI / DSD: Document references, ports and endpoints
device property: Add fwnode_get_next_parent()
device property: Add support for fwnode endpoints
device property: Make dev_fwnode() public
of: Add of_fwnode_handle() to convert device nodes to fwnode_handle
device property: Add fwnode_handle_get()
device property: Add support for remote endpoints
ACPI / property: Add support for remote endpoints
device property: Add fwnode_get_named_child_node()
ACPI / property: Add fwnode_get_next_child_node()
device property: Add fwnode_get_parent()
ACPI / property: Add possiblity to retrieve parent firmware node

+763 -107
+162
Documentation/acpi/dsd/graph.txt
··· 1 + Graphs 2 + 3 + 4 + _DSD 5 + ---- 6 + 7 + _DSD (Device Specific Data) [7] is a predefined ACPI device 8 + configuration object that can be used to convey information on 9 + hardware features which are not specifically covered by the ACPI 10 + specification [1][6]. There are two _DSD extensions that are relevant 11 + for graphs: property [4] and hierarchical data extensions [5]. The 12 + property extension provides generic key-value pairs whereas the 13 + hierarchical data extension supports nodes with references to other 14 + nodes, forming a tree. The nodes in the tree may contain properties as 15 + defined by the property extension. The two extensions together provide 16 + a tree-like structure with zero or more properties (key-value pairs) 17 + in each node of the tree. 18 + 19 + The data structure may be accessed at runtime by using the device_* 20 + and fwnode_* functions defined in include/linux/fwnode.h . 21 + 22 + Fwnode represents a generic firmware node object. It is independent on 23 + the firmware type. In ACPI, fwnodes are _DSD hierarchical data 24 + extensions objects. A device's _DSD object is represented by an 25 + fwnode. 26 + 27 + The data structure may be referenced to elsewhere in the ACPI tables 28 + by using a hard reference to the device itself and an index to the 29 + hierarchical data extension array on each depth. 30 + 31 + 32 + Ports and endpoints 33 + ------------------- 34 + 35 + The port and endpoint concepts are very similar to those in Devicetree 36 + [3]. A port represents an interface in a device, and an endpoint 37 + represents a connection to that interface. 38 + 39 + All port nodes are located under the device's "_DSD" node in the 40 + hierarchical data extension tree. The property extension related to 41 + each port node must contain the key "port" and an integer value which 42 + is the number of the port. The object it refers to should be called "PRTX", 43 + where "X" is the number of the port. 44 + 45 + Further on, endpoints are located under the individual port nodes. The 46 + first hierarchical data extension package list entry of the endpoint 47 + nodes must begin with "endpoint" and must be followed by the number 48 + of the endpoint. The object it refers to should be called "EPXY", where 49 + "X" is the number of the port and "Y" is the number of the endpoint. 50 + 51 + Each port node contains a property extension key "port", the value of 52 + which is the number of the port node. The each endpoint is similarly numbered 53 + with a property extension key "endpoint". Port numbers must be unique within a 54 + device and endpoint numbers must be unique within a port. 55 + 56 + The endpoint reference uses property extension with "remote-endpoint" property 57 + name followed by a reference in the same package. Such references consist of the 58 + the remote device reference, number of the port in the device and finally the 59 + number of the endpoint in that port. Individual references thus appear as: 60 + 61 + Package() { device, port_number, endpoint_number } 62 + 63 + The references to endpoints must be always done both ways, to the 64 + remote endpoint and back from the referred remote endpoint node. 65 + 66 + A simple example of this is show below: 67 + 68 + Scope (\_SB.PCI0.I2C2) 69 + { 70 + Device (CAM0) 71 + { 72 + Name (_DSD, Package () { 73 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 74 + Package () { 75 + Package () { "compatible", Package () { "nokia,smia" } }, 76 + }, 77 + ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 78 + Package () { 79 + Package () { "port0", "PRT0" }, 80 + } 81 + }) 82 + Name (PRT0, Package() { 83 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 84 + Package () { 85 + Package () { "port", 0 }, 86 + }, 87 + ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 88 + Package () { 89 + Package () { "endpoint0", "EP00" }, 90 + } 91 + }) 92 + Name (EP00, Package() { 93 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 94 + Package () { 95 + Package () { "endpoint", 0 }, 96 + Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, 4, 0 } }, 97 + } 98 + }) 99 + } 100 + } 101 + 102 + Scope (\_SB.PCI0) 103 + { 104 + Device (ISP) 105 + { 106 + Name (_DSD, Package () { 107 + ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 108 + Package () { 109 + Package () { "port4", "PRT4" }, 110 + } 111 + }) 112 + 113 + Name (PRT4, Package() { 114 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 115 + Package () { 116 + Package () { "port", 4 }, /* CSI-2 port number */ 117 + }, 118 + ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), 119 + Package () { 120 + Package () { "endpoint0", "EP40" }, 121 + } 122 + }) 123 + 124 + Name (EP40, Package() { 125 + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), 126 + Package () { 127 + Package () { "endpoint", 0 }, 128 + Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, 0, 0 } }, 129 + } 130 + }) 131 + } 132 + } 133 + 134 + Here, the port 0 of the "CAM0" device is connected to the port 4 of 135 + the "ISP" device and vice versa. 136 + 137 + 138 + References 139 + ---------- 140 + 141 + [1] _DSD (Device Specific Data) Implementation Guide. 142 + <URL:http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel-1_1.htm>, 143 + referenced 2016-10-03. 144 + 145 + [2] Devicetree. <URL:http://www.devicetree.org>, referenced 2016-10-03. 146 + 147 + [3] Documentation/devicetree/bindings/graph.txt 148 + 149 + [4] Device Properties UUID For _DSD. 150 + <URL:http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>, 151 + referenced 2016-10-04. 152 + 153 + [5] Hierarchical Data Extension UUID For _DSD. 154 + <URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf>, 155 + referenced 2016-10-04. 156 + 157 + [6] Advanced Configuration and Power Interface Specification. 158 + <URL:http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf>, 159 + referenced 2016-10-04. 160 + 161 + [7] _DSD Device Properties Usage Rules. 162 + Documentation/acpi/DSD-properties-rules.txt
+229 -30
drivers/acpi/property.c
··· 37 37 38 38 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 39 39 const union acpi_object *desc, 40 - struct acpi_device_data *data); 40 + struct acpi_device_data *data, 41 + struct fwnode_handle *parent); 41 42 static bool acpi_extract_properties(const union acpi_object *desc, 42 43 struct acpi_device_data *data); 43 44 44 45 static bool acpi_nondev_subnode_extract(const union acpi_object *desc, 45 46 acpi_handle handle, 46 47 const union acpi_object *link, 47 - struct list_head *list) 48 + struct list_head *list, 49 + struct fwnode_handle *parent) 48 50 { 49 51 struct acpi_data_node *dn; 50 52 bool result; ··· 57 55 58 56 dn->name = link->package.elements[0].string.pointer; 59 57 dn->fwnode.type = FWNODE_ACPI_DATA; 58 + dn->parent = parent; 60 59 INIT_LIST_HEAD(&dn->data.subnodes); 61 60 62 61 result = acpi_extract_properties(desc, &dn->data); ··· 74 71 */ 75 72 status = acpi_get_parent(handle, &scope); 76 73 if (ACPI_SUCCESS(status) 77 - && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data)) 74 + && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data, 75 + &dn->fwnode)) 78 76 result = true; 79 - } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) { 77 + } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data, 78 + &dn->fwnode)) { 80 79 result = true; 81 80 } 82 81 ··· 96 91 97 92 static bool acpi_nondev_subnode_data_ok(acpi_handle handle, 98 93 const union acpi_object *link, 99 - struct list_head *list) 94 + struct list_head *list, 95 + struct fwnode_handle *parent) 100 96 { 101 97 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER }; 102 98 acpi_status status; ··· 107 101 if (ACPI_FAILURE(status)) 108 102 return false; 109 103 110 - if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list)) 104 + if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list, 105 + parent)) 111 106 return true; 112 107 113 108 ACPI_FREE(buf.pointer); ··· 117 110 118 111 static bool acpi_nondev_subnode_ok(acpi_handle scope, 119 112 const union acpi_object *link, 120 - struct list_head *list) 113 + struct list_head *list, 114 + struct fwnode_handle *parent) 121 115 { 122 116 acpi_handle handle; 123 117 acpi_status status; ··· 131 123 if (ACPI_FAILURE(status)) 132 124 return false; 133 125 134 - return acpi_nondev_subnode_data_ok(handle, link, list); 126 + return acpi_nondev_subnode_data_ok(handle, link, list, parent); 135 127 } 136 128 137 129 static int acpi_add_nondev_subnodes(acpi_handle scope, 138 130 const union acpi_object *links, 139 - struct list_head *list) 131 + struct list_head *list, 132 + struct fwnode_handle *parent) 140 133 { 141 134 bool ret = false; 142 135 int i; ··· 159 150 /* The second one may be a string, a reference or a package. */ 160 151 switch (link->package.elements[1].type) { 161 152 case ACPI_TYPE_STRING: 162 - result = acpi_nondev_subnode_ok(scope, link, list); 153 + result = acpi_nondev_subnode_ok(scope, link, list, 154 + parent); 163 155 break; 164 156 case ACPI_TYPE_LOCAL_REFERENCE: 165 157 handle = link->package.elements[1].reference.handle; 166 - result = acpi_nondev_subnode_data_ok(handle, link, list); 158 + result = acpi_nondev_subnode_data_ok(handle, link, list, 159 + parent); 167 160 break; 168 161 case ACPI_TYPE_PACKAGE: 169 162 desc = &link->package.elements[1]; 170 - result = acpi_nondev_subnode_extract(desc, NULL, link, list); 163 + result = acpi_nondev_subnode_extract(desc, NULL, link, 164 + list, parent); 171 165 break; 172 166 default: 173 167 result = false; ··· 184 172 185 173 static bool acpi_enumerate_nondev_subnodes(acpi_handle scope, 186 174 const union acpi_object *desc, 187 - struct acpi_device_data *data) 175 + struct acpi_device_data *data, 176 + struct fwnode_handle *parent) 188 177 { 189 178 int i; 190 179 ··· 207 194 if (memcmp(uuid->buffer.pointer, ads_uuid, sizeof(ads_uuid))) 208 195 continue; 209 196 210 - return acpi_add_nondev_subnodes(scope, links, &data->subnodes); 197 + return acpi_add_nondev_subnodes(scope, links, &data->subnodes, 198 + parent); 211 199 } 212 200 213 201 return false; ··· 359 345 if (acpi_of) 360 346 acpi_init_of_compatible(adev); 361 347 } 362 - if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, &adev->data)) 348 + if (acpi_enumerate_nondev_subnodes(adev->handle, buf.pointer, 349 + &adev->data, acpi_fwnode_handle(adev))) 363 350 adev->data.pointer = buf.pointer; 364 351 365 352 if (!adev->data.pointer) { ··· 714 699 return ret; 715 700 716 701 *(char **)val = obj->string.pointer; 702 + 703 + return 1; 717 704 } else { 718 705 ret = -EINVAL; 719 706 } ··· 725 708 int acpi_dev_prop_read_single(struct acpi_device *adev, const char *propname, 726 709 enum dev_prop_type proptype, void *val) 727 710 { 728 - return adev ? acpi_data_prop_read_single(&adev->data, propname, proptype, val) : -EINVAL; 711 + int ret; 712 + 713 + if (!adev) 714 + return -EINVAL; 715 + 716 + ret = acpi_data_prop_read_single(&adev->data, propname, proptype, val); 717 + if (ret < 0 || proptype != ACPI_TYPE_STRING) 718 + return ret; 719 + return 0; 729 720 } 730 721 731 722 static int acpi_copy_property_array_u8(const union acpi_object *items, u8 *val, ··· 809 784 810 785 val[i] = items[i].string.pointer; 811 786 } 812 - return 0; 787 + return nval; 813 788 } 814 789 815 790 static int acpi_data_prop_read(struct acpi_device_data *data, ··· 823 798 824 799 if (val && nval == 1) { 825 800 ret = acpi_data_prop_read_single(data, propname, proptype, val); 826 - if (!ret) 801 + if (ret >= 0) 827 802 return ret; 828 803 } 829 804 ··· 834 809 if (!val) 835 810 return obj->package.count; 836 811 837 - if (nval > obj->package.count) 812 + if (proptype != DEV_PROP_STRING && nval > obj->package.count) 838 813 return -EOVERFLOW; 839 814 else if (nval <= 0) 840 815 return -EINVAL; ··· 855 830 ret = acpi_copy_property_array_u64(items, (u64 *)val, nval); 856 831 break; 857 832 case DEV_PROP_STRING: 858 - ret = acpi_copy_property_array_string(items, (char **)val, nval); 833 + ret = acpi_copy_property_array_string( 834 + items, (char **)val, 835 + min_t(u32, nval, obj->package.count)); 859 836 break; 860 837 default: 861 838 ret = -EINVAL; ··· 892 865 } 893 866 894 867 /** 895 - * acpi_get_next_subnode - Return the next child node handle for a device. 896 - * @dev: Device to find the next child node for. 868 + * acpi_get_next_subnode - Return the next child node handle for a fwnode 869 + * @fwnode: Firmware node to find the next child node for. 897 870 * @child: Handle to one of the device's child nodes or a null handle. 898 871 */ 899 - struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 872 + struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode, 900 873 struct fwnode_handle *child) 901 874 { 902 - struct acpi_device *adev = ACPI_COMPANION(dev); 875 + struct acpi_device *adev = to_acpi_device_node(fwnode); 903 876 struct list_head *head, *next; 904 877 905 - if (!adev) 906 - return NULL; 907 - 908 878 if (!child || child->type == FWNODE_ACPI) { 909 - head = &adev->children; 879 + if (adev) 880 + head = &adev->children; 881 + else 882 + goto nondev; 883 + 910 884 if (list_empty(head)) 911 885 goto nondev; 912 886 ··· 916 888 next = adev->node.next; 917 889 if (next == head) { 918 890 child = NULL; 919 - adev = ACPI_COMPANION(dev); 920 891 goto nondev; 921 892 } 922 893 adev = list_entry(next, struct acpi_device, node); ··· 927 900 928 901 nondev: 929 902 if (!child || child->type == FWNODE_ACPI_DATA) { 903 + struct acpi_data_node *data = to_acpi_data_node(fwnode); 930 904 struct acpi_data_node *dn; 931 905 932 - head = &adev->data.subnodes; 906 + if (adev) 907 + head = &adev->data.subnodes; 908 + else if (data) 909 + head = &data->data.subnodes; 910 + else 911 + return NULL; 912 + 933 913 if (list_empty(head)) 934 914 return NULL; 935 915 ··· 953 919 return &dn->fwnode; 954 920 } 955 921 return NULL; 922 + } 923 + 924 + /** 925 + * acpi_node_get_parent - Return parent fwnode of this fwnode 926 + * @fwnode: Firmware node whose parent to get 927 + * 928 + * Returns parent node of an ACPI device or data firmware node or %NULL if 929 + * not available. 930 + */ 931 + struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode) 932 + { 933 + if (is_acpi_data_node(fwnode)) { 934 + /* All data nodes have parent pointer so just return that */ 935 + return to_acpi_data_node(fwnode)->parent; 936 + } else if (is_acpi_device_node(fwnode)) { 937 + acpi_handle handle, parent_handle; 938 + 939 + handle = to_acpi_device_node(fwnode)->handle; 940 + if (ACPI_SUCCESS(acpi_get_parent(handle, &parent_handle))) { 941 + struct acpi_device *adev; 942 + 943 + if (!acpi_bus_get_device(parent_handle, &adev)) 944 + return acpi_fwnode_handle(adev); 945 + } 946 + } 947 + 948 + return NULL; 949 + } 950 + 951 + /** 952 + * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node 953 + * @fwnode: Pointer to the parent firmware node 954 + * @prev: Previous endpoint node or %NULL to get the first 955 + * 956 + * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns 957 + * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case 958 + * of success the next endpoint is returned. 959 + */ 960 + struct fwnode_handle *acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode, 961 + struct fwnode_handle *prev) 962 + { 963 + struct fwnode_handle *port = NULL; 964 + struct fwnode_handle *endpoint; 965 + 966 + if (!prev) { 967 + do { 968 + port = fwnode_get_next_child_node(fwnode, port); 969 + /* Ports must have port property */ 970 + if (fwnode_property_present(port, "port")) 971 + break; 972 + } while (port); 973 + } else { 974 + port = fwnode_get_parent(prev); 975 + } 976 + 977 + if (!port) 978 + return NULL; 979 + 980 + endpoint = fwnode_get_next_child_node(port, prev); 981 + while (!endpoint) { 982 + port = fwnode_get_next_child_node(fwnode, port); 983 + if (!port) 984 + break; 985 + if (fwnode_property_present(port, "port")) 986 + endpoint = fwnode_get_next_child_node(port, NULL); 987 + } 988 + 989 + if (endpoint) { 990 + /* Endpoints must have "endpoint" property */ 991 + if (!fwnode_property_present(endpoint, "endpoint")) 992 + return ERR_PTR(-EPROTO); 993 + } 994 + 995 + return endpoint; 996 + } 997 + 998 + /** 999 + * acpi_graph_get_child_prop_value - Return a child with a given property value 1000 + * @fwnode: device fwnode 1001 + * @prop_name: The name of the property to look for 1002 + * @val: the desired property value 1003 + * 1004 + * Return the port node corresponding to a given port number. Returns 1005 + * the child node on success, NULL otherwise. 1006 + */ 1007 + static struct fwnode_handle *acpi_graph_get_child_prop_value( 1008 + struct fwnode_handle *fwnode, const char *prop_name, unsigned int val) 1009 + { 1010 + struct fwnode_handle *child; 1011 + 1012 + fwnode_for_each_child_node(fwnode, child) { 1013 + u32 nr; 1014 + 1015 + if (!fwnode_property_read_u32(fwnode, prop_name, &nr)) 1016 + continue; 1017 + 1018 + if (val == nr) 1019 + return child; 1020 + } 1021 + 1022 + return NULL; 1023 + } 1024 + 1025 + 1026 + /** 1027 + * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint 1028 + * @fwnode: Endpoint firmware node pointing to a remote device 1029 + * @parent: Firmware node of remote port parent is filled here if not %NULL 1030 + * @port: Firmware node of remote port is filled here if not %NULL 1031 + * @endpoint: Firmware node of remote endpoint is filled here if not %NULL 1032 + * 1033 + * Function parses remote end of ACPI firmware remote endpoint and fills in 1034 + * fields requested by the caller. Returns %0 in case of success and 1035 + * negative errno otherwise. 1036 + */ 1037 + int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode, 1038 + struct fwnode_handle **parent, 1039 + struct fwnode_handle **port, 1040 + struct fwnode_handle **endpoint) 1041 + { 1042 + unsigned int port_nr, endpoint_nr; 1043 + struct acpi_reference_args args; 1044 + int ret; 1045 + 1046 + memset(&args, 0, sizeof(args)); 1047 + ret = acpi_node_get_property_reference(fwnode, "remote-endpoint", 0, 1048 + &args); 1049 + if (ret) 1050 + return ret; 1051 + 1052 + /* 1053 + * Always require two arguments with the reference: port and 1054 + * endpoint indices. 1055 + */ 1056 + if (args.nargs != 2) 1057 + return -EPROTO; 1058 + 1059 + fwnode = acpi_fwnode_handle(args.adev); 1060 + port_nr = args.args[0]; 1061 + endpoint_nr = args.args[1]; 1062 + 1063 + if (parent) 1064 + *parent = fwnode; 1065 + 1066 + if (!port && !endpoint) 1067 + return 0; 1068 + 1069 + fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr); 1070 + if (!fwnode) 1071 + return -EPROTO; 1072 + 1073 + if (port) 1074 + *port = fwnode; 1075 + 1076 + if (!endpoint) 1077 + return 0; 1078 + 1079 + fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint", 1080 + endpoint_nr); 1081 + if (!fwnode) 1082 + return -EPROTO; 1083 + 1084 + *endpoint = fwnode; 1085 + 1086 + return 0; 956 1087 }
+295 -73
drivers/base/property.c
··· 15 15 #include <linux/kernel.h> 16 16 #include <linux/of.h> 17 17 #include <linux/of_address.h> 18 + #include <linux/of_graph.h> 18 19 #include <linux/property.h> 19 20 #include <linux/etherdevice.h> 20 21 #include <linux/phy.h> ··· 147 146 const char *propname, 148 147 const char **strings, size_t nval) 149 148 { 149 + const struct property_entry *prop; 150 150 const void *pointer; 151 - size_t length = nval * sizeof(*strings); 151 + size_t array_len, length; 152 + 153 + /* Find out the array length. */ 154 + prop = pset_prop_get(pset, propname); 155 + if (!prop) 156 + return -EINVAL; 157 + 158 + if (!prop->is_array) 159 + /* The array length for a non-array string property is 1. */ 160 + array_len = 1; 161 + else 162 + /* Find the length of an array. */ 163 + array_len = pset_prop_count_elems_of_size(pset, propname, 164 + sizeof(const char *)); 165 + 166 + /* Return how many there are if strings is NULL. */ 167 + if (!strings) 168 + return array_len; 169 + 170 + array_len = min(nval, array_len); 171 + length = array_len * sizeof(*strings); 152 172 153 173 pointer = pset_prop_find(pset, propname, length); 154 174 if (IS_ERR(pointer)) 155 175 return PTR_ERR(pointer); 156 176 157 177 memcpy(strings, pointer, length); 158 - return 0; 178 + 179 + return array_len; 159 180 } 160 181 161 - static int pset_prop_read_string(struct property_set *pset, 162 - const char *propname, const char **strings) 163 - { 164 - const struct property_entry *prop; 165 - const char * const *pointer; 166 - 167 - prop = pset_prop_get(pset, propname); 168 - if (!prop) 169 - return -EINVAL; 170 - if (!prop->is_string) 171 - return -EILSEQ; 172 - if (prop->is_array) { 173 - pointer = prop->pointer.str; 174 - if (!pointer) 175 - return -ENODATA; 176 - } else { 177 - pointer = &prop->value.str; 178 - if (*pointer && strnlen(*pointer, prop->length) >= prop->length) 179 - return -EILSEQ; 180 - } 181 - 182 - *strings = *pointer; 183 - return 0; 184 - } 185 - 186 - static inline struct fwnode_handle *dev_fwnode(struct device *dev) 182 + struct fwnode_handle *dev_fwnode(struct device *dev) 187 183 { 188 184 return IS_ENABLED(CONFIG_OF) && dev->of_node ? 189 185 &dev->of_node->fwnode : dev->fwnode; 190 186 } 187 + EXPORT_SYMBOL_GPL(dev_fwnode); 191 188 192 189 /** 193 190 * device_property_present - check if a property of a device is present ··· 339 340 * Function reads an array of string properties with @propname from the device 340 341 * firmware description and stores them to @val if found. 341 342 * 342 - * Return: number of values if @val was %NULL, 343 - * %0 if the property was found (success), 343 + * Return: number of values read on success if @val is non-NULL, 344 + * number of values available on success if @val is NULL, 344 345 * %-EINVAL if given arguments are not valid, 345 346 * %-ENODATA if the property does not have a value, 346 347 * %-EPROTO or %-EILSEQ if the property is not an array of strings, ··· 552 553 return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, 553 554 val, nval); 554 555 else if (is_pset_node(fwnode)) 555 - return val ? 556 - pset_prop_read_string_array(to_pset_node(fwnode), 557 - propname, val, nval) : 558 - pset_prop_count_elems_of_size(to_pset_node(fwnode), 559 - propname, 560 - sizeof(const char *)); 561 - return -ENXIO; 562 - } 563 - 564 - static int __fwnode_property_read_string(struct fwnode_handle *fwnode, 565 - const char *propname, const char **val) 566 - { 567 - if (is_of_node(fwnode)) 568 - return of_property_read_string(to_of_node(fwnode), propname, val); 569 - else if (is_acpi_node(fwnode)) 570 - return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, 571 - val, 1); 572 - else if (is_pset_node(fwnode)) 573 - return pset_prop_read_string(to_pset_node(fwnode), propname, val); 556 + return pset_prop_read_string_array(to_pset_node(fwnode), 557 + propname, val, nval); 574 558 return -ENXIO; 575 559 } 576 560 ··· 567 585 * Read an string list property @propname from the given firmware node and store 568 586 * them to @val if found. 569 587 * 570 - * Return: number of values if @val was %NULL, 571 - * %0 if the property was found (success), 588 + * Return: number of values read on success if @val is non-NULL, 589 + * number of values available on success if @val is NULL, 572 590 * %-EINVAL if given arguments are not valid, 573 591 * %-ENODATA if the property does not have a value, 574 - * %-EPROTO if the property is not an array of strings, 592 + * %-EPROTO or %-EILSEQ if the property is not an array of strings, 575 593 * %-EOVERFLOW if the size of the property is not as expected, 576 594 * %-ENXIO if no suitable firmware interface is present. 577 595 */ ··· 608 626 int fwnode_property_read_string(struct fwnode_handle *fwnode, 609 627 const char *propname, const char **val) 610 628 { 611 - int ret; 629 + int ret = fwnode_property_read_string_array(fwnode, propname, val, 1); 612 630 613 - ret = __fwnode_property_read_string(fwnode, propname, val); 614 - if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) && 615 - !IS_ERR_OR_NULL(fwnode->secondary)) 616 - ret = __fwnode_property_read_string(fwnode->secondary, 617 - propname, val); 618 - return ret; 631 + return ret < 0 ? ret : 0; 619 632 } 620 633 EXPORT_SYMBOL_GPL(fwnode_property_read_string); 621 634 ··· 909 932 EXPORT_SYMBOL_GPL(device_add_properties); 910 933 911 934 /** 935 + * fwnode_get_next_parent - Iterate to the node's parent 936 + * @fwnode: Firmware whose parent is retrieved 937 + * 938 + * This is like fwnode_get_parent() except that it drops the refcount 939 + * on the passed node, making it suitable for iterating through a 940 + * node's parents. 941 + * 942 + * Returns a node pointer with refcount incremented, use 943 + * fwnode_handle_node() on it when done. 944 + */ 945 + struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode) 946 + { 947 + struct fwnode_handle *parent = fwnode_get_parent(fwnode); 948 + 949 + fwnode_handle_put(fwnode); 950 + 951 + return parent; 952 + } 953 + EXPORT_SYMBOL_GPL(fwnode_get_next_parent); 954 + 955 + /** 956 + * fwnode_get_parent - Return parent firwmare node 957 + * @fwnode: Firmware whose parent is retrieved 958 + * 959 + * Return parent firmware node of the given node if possible or %NULL if no 960 + * parent was available. 961 + */ 962 + struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode) 963 + { 964 + struct fwnode_handle *parent = NULL; 965 + 966 + if (is_of_node(fwnode)) { 967 + struct device_node *node; 968 + 969 + node = of_get_parent(to_of_node(fwnode)); 970 + if (node) 971 + parent = &node->fwnode; 972 + } else if (is_acpi_node(fwnode)) { 973 + parent = acpi_node_get_parent(fwnode); 974 + } 975 + 976 + return parent; 977 + } 978 + EXPORT_SYMBOL_GPL(fwnode_get_parent); 979 + 980 + /** 981 + * fwnode_get_next_child_node - Return the next child node handle for a node 982 + * @fwnode: Firmware node to find the next child node for. 983 + * @child: Handle to one of the node's child nodes or a %NULL handle. 984 + */ 985 + struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode, 986 + struct fwnode_handle *child) 987 + { 988 + if (is_of_node(fwnode)) { 989 + struct device_node *node; 990 + 991 + node = of_get_next_available_child(to_of_node(fwnode), 992 + to_of_node(child)); 993 + if (node) 994 + return &node->fwnode; 995 + } else if (is_acpi_node(fwnode)) { 996 + return acpi_get_next_subnode(fwnode, child); 997 + } 998 + 999 + return NULL; 1000 + } 1001 + EXPORT_SYMBOL_GPL(fwnode_get_next_child_node); 1002 + 1003 + /** 912 1004 * device_get_next_child_node - Return the next child node handle for a device 913 1005 * @dev: Device to find the next child node for. 914 1006 * @child: Handle to one of the device's child nodes or a null handle. ··· 985 939 struct fwnode_handle *device_get_next_child_node(struct device *dev, 986 940 struct fwnode_handle *child) 987 941 { 988 - if (IS_ENABLED(CONFIG_OF) && dev->of_node) { 989 - struct device_node *node; 942 + struct acpi_device *adev = ACPI_COMPANION(dev); 943 + struct fwnode_handle *fwnode = NULL; 990 944 991 - node = of_get_next_available_child(dev->of_node, to_of_node(child)); 992 - if (node) 993 - return &node->fwnode; 994 - } else if (IS_ENABLED(CONFIG_ACPI)) { 995 - return acpi_get_next_subnode(dev, child); 996 - } 997 - return NULL; 945 + if (dev->of_node) 946 + fwnode = &dev->of_node->fwnode; 947 + else if (adev) 948 + fwnode = acpi_fwnode_handle(adev); 949 + 950 + return fwnode_get_next_child_node(fwnode, child); 998 951 } 999 952 EXPORT_SYMBOL_GPL(device_get_next_child_node); 1000 953 1001 954 /** 1002 - * device_get_named_child_node - Return first matching named child node handle 1003 - * @dev: Device to find the named child node for. 955 + * fwnode_get_named_child_node - Return first matching named child node handle 956 + * @fwnode: Firmware node to find the named child node for. 1004 957 * @childname: String to match child node name against. 1005 958 */ 1006 - struct fwnode_handle *device_get_named_child_node(struct device *dev, 959 + struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode, 1007 960 const char *childname) 1008 961 { 1009 962 struct fwnode_handle *child; 1010 963 1011 964 /* 1012 - * Find first matching named child node of this device. 965 + * Find first matching named child node of this fwnode. 1013 966 * For ACPI this will be a data only sub-node. 1014 967 */ 1015 - device_for_each_child_node(dev, child) { 968 + fwnode_for_each_child_node(fwnode, child) { 1016 969 if (is_of_node(child)) { 1017 970 if (!of_node_cmp(to_of_node(child)->name, childname)) 1018 971 return child; ··· 1023 978 1024 979 return NULL; 1025 980 } 981 + EXPORT_SYMBOL_GPL(fwnode_get_named_child_node); 982 + 983 + /** 984 + * device_get_named_child_node - Return first matching named child node handle 985 + * @dev: Device to find the named child node for. 986 + * @childname: String to match child node name against. 987 + */ 988 + struct fwnode_handle *device_get_named_child_node(struct device *dev, 989 + const char *childname) 990 + { 991 + return fwnode_get_named_child_node(dev_fwnode(dev), childname); 992 + } 1026 993 EXPORT_SYMBOL_GPL(device_get_named_child_node); 994 + 995 + /** 996 + * fwnode_handle_get - Obtain a reference to a device node 997 + * @fwnode: Pointer to the device node to obtain the reference to. 998 + */ 999 + void fwnode_handle_get(struct fwnode_handle *fwnode) 1000 + { 1001 + if (is_of_node(fwnode)) 1002 + of_node_get(to_of_node(fwnode)); 1003 + } 1004 + EXPORT_SYMBOL_GPL(fwnode_handle_get); 1027 1005 1028 1006 /** 1029 1007 * fwnode_handle_put - Drop reference to a device node ··· 1185 1117 return device_get_mac_addr(dev, "address", addr, alen); 1186 1118 } 1187 1119 EXPORT_SYMBOL(device_get_mac_address); 1120 + 1121 + /** 1122 + * device_graph_get_next_endpoint - Get next endpoint firmware node 1123 + * @fwnode: Pointer to the parent firmware node 1124 + * @prev: Previous endpoint node or %NULL to get the first 1125 + * 1126 + * Returns an endpoint firmware node pointer or %NULL if no more endpoints 1127 + * are available. 1128 + */ 1129 + struct fwnode_handle * 1130 + fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode, 1131 + struct fwnode_handle *prev) 1132 + { 1133 + struct fwnode_handle *endpoint = NULL; 1134 + 1135 + if (is_of_node(fwnode)) { 1136 + struct device_node *node; 1137 + 1138 + node = of_graph_get_next_endpoint(to_of_node(fwnode), 1139 + to_of_node(prev)); 1140 + 1141 + if (node) 1142 + endpoint = &node->fwnode; 1143 + } else if (is_acpi_node(fwnode)) { 1144 + endpoint = acpi_graph_get_next_endpoint(fwnode, prev); 1145 + if (IS_ERR(endpoint)) 1146 + endpoint = NULL; 1147 + } 1148 + 1149 + return endpoint; 1150 + 1151 + } 1152 + EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); 1153 + 1154 + /** 1155 + * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device 1156 + * @fwnode: Endpoint firmware node pointing to the remote endpoint 1157 + * 1158 + * Extracts firmware node of a remote device the @fwnode points to. 1159 + */ 1160 + struct fwnode_handle * 1161 + fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode) 1162 + { 1163 + struct fwnode_handle *parent = NULL; 1164 + 1165 + if (is_of_node(fwnode)) { 1166 + struct device_node *node; 1167 + 1168 + node = of_graph_get_remote_port_parent(to_of_node(fwnode)); 1169 + if (node) 1170 + parent = &node->fwnode; 1171 + } else if (is_acpi_node(fwnode)) { 1172 + int ret; 1173 + 1174 + ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL, 1175 + NULL); 1176 + if (ret) 1177 + return NULL; 1178 + } 1179 + 1180 + return parent; 1181 + } 1182 + EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent); 1183 + 1184 + /** 1185 + * fwnode_graph_get_remote_port - Return fwnode of a remote port 1186 + * @fwnode: Endpoint firmware node pointing to the remote endpoint 1187 + * 1188 + * Extracts firmware node of a remote port the @fwnode points to. 1189 + */ 1190 + struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode) 1191 + { 1192 + struct fwnode_handle *port = NULL; 1193 + 1194 + if (is_of_node(fwnode)) { 1195 + struct device_node *node; 1196 + 1197 + node = of_graph_get_remote_port(to_of_node(fwnode)); 1198 + if (node) 1199 + port = &node->fwnode; 1200 + } else if (is_acpi_node(fwnode)) { 1201 + int ret; 1202 + 1203 + ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL); 1204 + if (ret) 1205 + return NULL; 1206 + } 1207 + 1208 + return port; 1209 + } 1210 + EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port); 1211 + 1212 + /** 1213 + * fwnode_graph_get_remote_endpoint - Return fwnode of a remote endpoint 1214 + * @fwnode: Endpoint firmware node pointing to the remote endpoint 1215 + * 1216 + * Extracts firmware node of a remote endpoint the @fwnode points to. 1217 + */ 1218 + struct fwnode_handle * 1219 + fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode) 1220 + { 1221 + struct fwnode_handle *endpoint = NULL; 1222 + 1223 + if (is_of_node(fwnode)) { 1224 + struct device_node *node; 1225 + 1226 + node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint", 1227 + 0); 1228 + if (node) 1229 + endpoint = &node->fwnode; 1230 + } else if (is_acpi_node(fwnode)) { 1231 + int ret; 1232 + 1233 + ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, 1234 + &endpoint); 1235 + if (ret) 1236 + return NULL; 1237 + } 1238 + 1239 + return endpoint; 1240 + } 1241 + EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint); 1242 + 1243 + /** 1244 + * fwnode_graph_parse_endpoint - parse common endpoint node properties 1245 + * @fwnode: pointer to endpoint fwnode_handle 1246 + * @endpoint: pointer to the fwnode endpoint data structure 1247 + * 1248 + * Parse @fwnode representing a graph endpoint node and store the 1249 + * information in @endpoint. The caller must hold a reference to 1250 + * @fwnode. 1251 + */ 1252 + int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode, 1253 + struct fwnode_endpoint *endpoint) 1254 + { 1255 + struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode); 1256 + 1257 + memset(endpoint, 0, sizeof(*endpoint)); 1258 + 1259 + endpoint->local_fwnode = fwnode; 1260 + 1261 + if (is_acpi_node(port_fwnode)) { 1262 + fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); 1263 + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); 1264 + } else { 1265 + fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port); 1266 + fwnode_property_read_u32(fwnode, "reg", &endpoint->id); 1267 + } 1268 + 1269 + fwnode_handle_put(port_fwnode); 1270 + 1271 + return 0; 1272 + } 1273 + EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
+1
include/acpi/acpi_bus.h
··· 387 387 const char *name; 388 388 acpi_handle handle; 389 389 struct fwnode_handle fwnode; 390 + struct fwnode_handle *parent; 390 391 struct acpi_device_data data; 391 392 struct list_head sibling; 392 393 struct kobject kobj;
+34 -4
include/linux/acpi.h
··· 998 998 int acpi_dev_prop_read(struct acpi_device *adev, const char *propname, 999 999 enum dev_prop_type proptype, void *val, size_t nval); 1000 1000 1001 - struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 1002 - struct fwnode_handle *subnode); 1001 + struct fwnode_handle *acpi_get_next_subnode(struct fwnode_handle *fwnode, 1002 + struct fwnode_handle *child); 1003 + struct fwnode_handle *acpi_node_get_parent(struct fwnode_handle *fwnode); 1004 + 1005 + struct fwnode_handle *acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode, 1006 + struct fwnode_handle *prev); 1007 + int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode, 1008 + struct fwnode_handle **remote, 1009 + struct fwnode_handle **port, 1010 + struct fwnode_handle **endpoint); 1003 1011 1004 1012 struct acpi_probe_entry; 1005 1013 typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *, ··· 1124 1116 return -ENXIO; 1125 1117 } 1126 1118 1127 - static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev, 1128 - struct fwnode_handle *subnode) 1119 + static inline struct fwnode_handle * 1120 + acpi_get_next_subnode(struct fwnode_handle *fwnode, struct fwnode_handle *child) 1129 1121 { 1130 1122 return NULL; 1123 + } 1124 + 1125 + static inline struct fwnode_handle * 1126 + acpi_node_get_parent(struct fwnode_handle *fwnode) 1127 + { 1128 + return NULL; 1129 + } 1130 + 1131 + static inline struct fwnode_handle * 1132 + acpi_graph_get_next_endpoint(struct fwnode_handle *fwnode, 1133 + struct fwnode_handle *prev) 1134 + { 1135 + return ERR_PTR(-ENXIO); 1136 + } 1137 + 1138 + static inline int 1139 + acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode, 1140 + struct fwnode_handle **remote, 1141 + struct fwnode_handle **port, 1142 + struct fwnode_handle **endpoint) 1143 + { 1144 + return -ENXIO; 1131 1145 } 1132 1146 1133 1147 #define ACPI_DECLARE_PROBE_ENTRY(table, name, table_id, subtable, valid, data, fn) \
+12
include/linux/fwnode.h
··· 27 27 struct fwnode_handle *secondary; 28 28 }; 29 29 30 + /** 31 + * struct fwnode_endpoint - Fwnode graph endpoint 32 + * @port: Port number 33 + * @id: Endpoint id 34 + * @local_fwnode: reference to the related fwnode 35 + */ 36 + struct fwnode_endpoint { 37 + unsigned int port; 38 + unsigned int id; 39 + const struct fwnode_handle *local_fwnode; 40 + }; 41 + 30 42 #endif
+4
include/linux/of.h
··· 159 159 container_of(fwnode, struct device_node, fwnode) : NULL; 160 160 } 161 161 162 + #define of_fwnode_handle(node) (&(node)->fwnode) 163 + 162 164 static inline bool of_have_populated_dt(void) 163 165 { 164 166 return of_root != NULL; ··· 603 601 { 604 602 return NULL; 605 603 } 604 + 605 + #define of_fwnode_handle(node) NULL 606 606 607 607 static inline bool of_have_populated_dt(void) 608 608 {
+26
include/linux/property.h
··· 33 33 DEV_DMA_COHERENT, 34 34 }; 35 35 36 + struct fwnode_handle *dev_fwnode(struct device *dev); 37 + 36 38 bool device_property_present(struct device *dev, const char *propname); 37 39 int device_property_read_u8_array(struct device *dev, const char *propname, 38 40 u8 *val, size_t nval); ··· 72 70 int fwnode_property_match_string(struct fwnode_handle *fwnode, 73 71 const char *propname, const char *string); 74 72 73 + struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode); 74 + struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode); 75 + struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode, 76 + struct fwnode_handle *child); 77 + 78 + #define fwnode_for_each_child_node(fwnode, child) \ 79 + for (child = fwnode_get_next_child_node(fwnode, NULL); child; \ 80 + child = fwnode_get_next_child_node(fwnode, child)) 81 + 75 82 struct fwnode_handle *device_get_next_child_node(struct device *dev, 76 83 struct fwnode_handle *child); 77 84 ··· 88 77 for (child = device_get_next_child_node(dev, NULL); child; \ 89 78 child = device_get_next_child_node(dev, child)) 90 79 80 + struct fwnode_handle *fwnode_get_named_child_node(struct fwnode_handle *fwnode, 81 + const char *childname); 91 82 struct fwnode_handle *device_get_named_child_node(struct device *dev, 92 83 const char *childname); 93 84 85 + void fwnode_handle_get(struct fwnode_handle *fwnode); 94 86 void fwnode_handle_put(struct fwnode_handle *fwnode); 95 87 96 88 unsigned int device_get_child_node_count(struct device *dev); ··· 271 257 int device_get_phy_mode(struct device *dev); 272 258 273 259 void *device_get_mac_address(struct device *dev, char *addr, int alen); 260 + 261 + struct fwnode_handle *fwnode_graph_get_next_endpoint( 262 + struct fwnode_handle *fwnode, struct fwnode_handle *prev); 263 + struct fwnode_handle *fwnode_graph_get_remote_port_parent( 264 + struct fwnode_handle *fwnode); 265 + struct fwnode_handle *fwnode_graph_get_remote_port( 266 + struct fwnode_handle *fwnode); 267 + struct fwnode_handle *fwnode_graph_get_remote_endpoint( 268 + struct fwnode_handle *fwnode); 269 + 270 + int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode, 271 + struct fwnode_endpoint *endpoint); 274 272 275 273 #endif /* _LINUX_PROPERTY_H_ */