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

Merge tag 'of-graph-for-4.0' of git://git.pengutronix.de/git/pza/linux into for-next

Pull of-graph helpers from Philipp Zabel:
of: Add of-graph helpers to loop over endpoints and find ports by id

This series converts of_graph_get_next_endpoint to decrement the refcount of
the passed prev parameter. This allows to add a for_each_endpoint_of_node
helper macro to loop over all endpoints in a device tree node.
The of_graph_get_port_by_id function is added to retrieve a port by its known
port id (contained in the reg property) from the device tree.

+61 -48
+2 -11
drivers/coresight/of_coresight.c
··· 52 52 endpoint, of_dev_node_match); 53 53 } 54 54 55 - static struct device_node *of_get_coresight_endpoint( 56 - const struct device_node *parent, struct device_node *prev) 57 - { 58 - struct device_node *node = of_graph_get_next_endpoint(parent, prev); 59 - 60 - of_node_put(prev); 61 - return node; 62 - } 63 - 64 55 static void of_coresight_get_ports(struct device_node *node, 65 56 int *nr_inport, int *nr_outport) 66 57 { ··· 59 68 int in = 0, out = 0; 60 69 61 70 do { 62 - ep = of_get_coresight_endpoint(node, ep); 71 + ep = of_graph_get_next_endpoint(node, ep); 63 72 if (!ep) 64 73 break; 65 74 ··· 131 140 /* Iterate through each port to discover topology */ 132 141 do { 133 142 /* Get a handle on a port */ 134 - ep = of_get_coresight_endpoint(node, ep); 143 + ep = of_graph_get_next_endpoint(node, ep); 135 144 if (!ep) 136 145 break; 137 146
+1 -10
drivers/gpu/drm/imx/imx-drm-core.c
··· 431 431 } 432 432 EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of); 433 433 434 - static struct device_node *imx_drm_of_get_next_endpoint( 435 - const struct device_node *parent, struct device_node *prev) 436 - { 437 - struct device_node *node = of_graph_get_next_endpoint(parent, prev); 438 - 439 - of_node_put(prev); 440 - return node; 441 - } 442 - 443 434 /* 444 435 * @node: device tree node containing encoder input ports 445 436 * @encoder: drm_encoder ··· 448 457 return -EINVAL; 449 458 450 459 do { 451 - ep = imx_drm_of_get_next_endpoint(node, ep); 460 + ep = of_graph_get_next_endpoint(node, ep); 452 461 if (!ep) 453 462 break; 454 463
+4 -11
drivers/gpu/drm/rcar-du/rcar_du_kms.c
··· 206 206 enum rcar_du_encoder_type enc_type = RCAR_DU_ENCODER_NONE; 207 207 struct device_node *connector = NULL; 208 208 struct device_node *encoder = NULL; 209 - struct device_node *prev = NULL; 209 + struct device_node *ep_node = NULL; 210 210 struct device_node *entity_ep_node; 211 211 struct device_node *entity; 212 212 int ret; ··· 225 225 entity_ep_node = of_parse_phandle(ep->local_node, "remote-endpoint", 0); 226 226 227 227 while (1) { 228 - struct device_node *ep_node; 229 - 230 - ep_node = of_graph_get_next_endpoint(entity, prev); 231 - of_node_put(prev); 232 - prev = ep_node; 228 + ep_node = of_graph_get_next_endpoint(entity, ep_node); 233 229 234 230 if (!ep_node) 235 231 break; ··· 296 300 static int rcar_du_encoders_init(struct rcar_du_device *rcdu) 297 301 { 298 302 struct device_node *np = rcdu->dev->of_node; 299 - struct device_node *prev = NULL; 303 + struct device_node *ep_node = NULL; 300 304 unsigned int num_encoders = 0; 301 305 302 306 /* ··· 304 308 * pipeline. 305 309 */ 306 310 while (1) { 307 - struct device_node *ep_node; 308 311 enum rcar_du_output output; 309 312 struct of_endpoint ep; 310 313 unsigned int i; 311 314 int ret; 312 315 313 - ep_node = of_graph_get_next_endpoint(np, prev); 314 - of_node_put(prev); 315 - prev = ep_node; 316 + ep_node = of_graph_get_next_endpoint(np, ep_node); 316 317 317 318 if (ep_node == NULL) 318 319 break;
-1
drivers/media/platform/am437x/am437x-vpfe.c
··· 2504 2504 GFP_KERNEL); 2505 2505 pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF; 2506 2506 pdata->asd[i]->match.of.node = rem; 2507 - of_node_put(endpoint); 2508 2507 of_node_put(rem); 2509 2508 } 2510 2509
+2 -1
drivers/media/platform/soc_camera/soc_camera.c
··· 1694 1694 if (!i) 1695 1695 soc_of_bind(ici, epn, ren->parent); 1696 1696 1697 - of_node_put(epn); 1698 1697 of_node_put(ren); 1699 1698 1700 1699 if (i) { ··· 1701 1702 break; 1702 1703 } 1703 1704 } 1705 + 1706 + of_node_put(epn); 1704 1707 } 1705 1708 1706 1709 #else
+33 -8
drivers/of/base.c
··· 2083 2083 EXPORT_SYMBOL(of_graph_parse_endpoint); 2084 2084 2085 2085 /** 2086 + * of_graph_get_port_by_id() - get the port matching a given id 2087 + * @parent: pointer to the parent device node 2088 + * @id: id of the port 2089 + * 2090 + * Return: A 'port' node pointer with refcount incremented. The caller 2091 + * has to use of_node_put() on it when done. 2092 + */ 2093 + struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) 2094 + { 2095 + struct device_node *node, *port; 2096 + 2097 + node = of_get_child_by_name(parent, "ports"); 2098 + if (node) 2099 + parent = node; 2100 + 2101 + for_each_child_of_node(parent, port) { 2102 + u32 port_id = 0; 2103 + 2104 + if (of_node_cmp(port->name, "port") != 0) 2105 + continue; 2106 + of_property_read_u32(port, "reg", &port_id); 2107 + if (id == port_id) 2108 + break; 2109 + } 2110 + 2111 + of_node_put(node); 2112 + 2113 + return port; 2114 + } 2115 + EXPORT_SYMBOL(of_graph_get_port_by_id); 2116 + 2117 + /** 2086 2118 * of_graph_get_next_endpoint() - get next endpoint node 2087 2119 * @parent: pointer to the parent device node 2088 2120 * @prev: previous endpoint node, or NULL to get first 2089 2121 * 2090 2122 * Return: An 'endpoint' node pointer with refcount incremented. Refcount 2091 - * of the passed @prev node is not decremented, the caller have to use 2092 - * of_node_put() on it when done. 2123 + * of the passed @prev node is decremented. 2093 2124 */ 2094 2125 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 2095 2126 struct device_node *prev) ··· 2156 2125 if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", 2157 2126 __func__, prev->full_name)) 2158 2127 return NULL; 2159 - 2160 - /* 2161 - * Avoid dropping prev node refcount to 0 when getting the next 2162 - * child below. 2163 - */ 2164 - of_node_get(prev); 2165 2128 } 2166 2129 2167 2130 while (1) {
+1 -6
drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
··· 164 164 165 165 pn = of_graph_get_remote_port_parent(n); 166 166 167 - if (!pn) { 168 - of_node_put(n); 167 + if (!pn) 169 168 continue; 170 - } 171 169 172 170 if (!of_device_is_available(pn) || omapdss_list_contains(pn)) { 173 171 of_node_put(pn); 174 - of_node_put(n); 175 172 continue; 176 173 } 177 174 178 175 omapdss_walk_device(pn, false); 179 - 180 - of_node_put(n); 181 176 } 182 177 } 183 178
+18
include/linux/of_graph.h
··· 26 26 const struct device_node *local_node; 27 27 }; 28 28 29 + /** 30 + * for_each_endpoint_of_node - iterate over every endpoint in a device node 31 + * @parent: parent device node containing ports and endpoints 32 + * @child: loop variable pointing to the current endpoint node 33 + * 34 + * When breaking out of the loop, of_node_put(child) has to be called manually. 35 + */ 36 + #define for_each_endpoint_of_node(parent, child) \ 37 + for (child = of_graph_get_next_endpoint(parent, NULL); child != NULL; \ 38 + child = of_graph_get_next_endpoint(parent, child)) 39 + 29 40 #ifdef CONFIG_OF 30 41 int of_graph_parse_endpoint(const struct device_node *node, 31 42 struct of_endpoint *endpoint); 43 + struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id); 32 44 struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, 33 45 struct device_node *previous); 34 46 struct device_node *of_graph_get_remote_port_parent( ··· 52 40 struct of_endpoint *endpoint) 53 41 { 54 42 return -ENOSYS; 43 + } 44 + 45 + static inline struct device_node *of_graph_get_port_by_id( 46 + struct device_node *node, u32 id) 47 + { 48 + return NULL; 55 49 } 56 50 57 51 static inline struct device_node *of_graph_get_next_endpoint(