From a3b398e6f2f169f09e60ba99745ca444d7de693e Mon Sep 17 00:00:00 2001 From: Smitha T Murthy Date: Wed, 21 Dec 2016 11:14:31 +0530 Subject: of: reserved_mem: set dma_ops for devices using reserved mem For some IPs, there may be virtual child devices created and for them its necessary to set the dma_ops if it's using reserved memory else it will call the dummy dma_ops during buffer operations for the child devices which will lead to memory mapping failure. Signed-off-by: Smitha T Murthy Signed-off-by: Pankaj Dubey Acked-by: Marek Szyprowski Signed-off-by: Rob Herring --- drivers/of/of_reserved_mem.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 366d8c3c7989..d507c3569a88 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -354,6 +354,10 @@ int of_reserved_mem_device_init_by_idx(struct device *dev, mutex_lock(&of_rmem_assigned_device_mutex); list_add(&rd->list, &of_rmem_assigned_device_list); mutex_unlock(&of_rmem_assigned_device_mutex); + /* ensure that dma_ops is set for virtual devices + * using reserved memory + */ + of_dma_configure(dev, np); dev_info(dev, "assigned reserved memory node %s\n", rmem->name); } else { -- cgit v1.2.3 From 30965eeab5c873ca7af410506e6f0965074bf702 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 24 Dec 2016 23:45:06 +0800 Subject: of: drop duplicate headers Drop duplicate headers string.h and of_platform.h. Signed-off-by: Geliang Tang Signed-off-by: Rob Herring --- drivers/of/overlay.c | 1 - drivers/of/resolver.c | 1 - drivers/of/unittest.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 0d4cda7050e0..d4e337ebcf0f 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 8bf12e904fd2..7ae9863cb0a4 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -18,7 +18,6 @@ #include #include #include -#include #include /* illegal phandle value (set when unresolved) */ diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 53c83d66eb7e..b4e823615f2c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From f1aa54840657fe822b026ab56b75088e08c92362 Mon Sep 17 00:00:00 2001 From: Guilherme G. Piccoli Date: Mon, 5 Dec 2016 11:59:16 -0200 Subject: of/irq: improve error report on irq discovery process failure On PowerPC machines some PCI slots might not have level triggered interrupts capability (also know as level signaled interrupts), leading of_irq_parse_pci() to complain by presenting error messages on the kernel log - in this case, the properties "interrupt-map" and "interrupt-map-mask" are not present on device's node in the device tree. This patch introduces a different message for this specific case, and also reduces its level from error to warning. Besides, we warn (once) that possibly some PCI slots on the system have no level triggered interrupts available. We changed some error return codes too on function of_irq_parse_raw() in order other failure's cases can be presented in a more precise way. Before this patch, when an adapter was plugged in a slot without level interrupts capabilitiy on PowerPC, we saw a generic error message like this: [54.239] pci 002d:70:00.0: of_irq_parse_pci() failed with rc=-22 Now, with this applied, we see the following specific message: [16.154] pci 0014:60:00.1: of_irq_parse_pci: no interrupt-map found, INTx interrupts not available Finally, we standardize the error path in of_irq_parse_raw() by always taking the fail path instead of returning directly from the loop. Signed-off-by: Guilherme G. Piccoli Signed-off-by: Rob Herring --- drivers/of/irq.c | 19 ++++++++++++------- drivers/of/of_pci_irq.c | 10 +++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3fda9a32defb..7c56b72d1dc6 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -104,7 +104,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) const __be32 *match_array = initial_match_array; const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; - int imaplen, match, i; + int imaplen, match, i, rc = -EINVAL; #ifdef DEBUG of_print_phandle_args("of_irq_parse_raw: ", out_irq); @@ -134,7 +134,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); if (out_irq->args_count != intsize) - return -EINVAL; + goto fail; /* Look for this #address-cells. We have to implement the old linux * trick of looking for the parent here as some device-trees rely on it @@ -153,8 +153,10 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) pr_debug(" -> addrsize=%d\n", addrsize); /* Range check so that the temporary buffer doesn't overflow */ - if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) + if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) { + rc = -EFAULT; goto fail; + } /* Precalculate the match array - this simplifies match loop */ for (i = 0; i < addrsize; i++) @@ -240,10 +242,11 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) newintsize, newaddrsize); /* Check for malformed properties */ - if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)) - goto fail; - if (imaplen < (newaddrsize + newintsize)) + if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS) + || (imaplen < (newaddrsize + newintsize))) { + rc = -EFAULT; goto fail; + } imap += newaddrsize + newintsize; imaplen -= newaddrsize + newintsize; @@ -271,11 +274,13 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) ipar = newpar; newpar = NULL; } + rc = -ENOENT; /* No interrupt-map found */ + fail: of_node_put(ipar); of_node_put(newpar); - return -EINVAL; + return rc; } EXPORT_SYMBOL_GPL(of_irq_parse_raw); diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 2306313c0029..c175d9cd0bb5 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c @@ -93,7 +93,15 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq goto err; return 0; err: - dev_err(&pdev->dev, "of_irq_parse_pci() failed with rc=%d\n", rc); + if (rc == -ENOENT) { + dev_warn(&pdev->dev, + "%s: no interrupt-map found, INTx interrupts not available\n", + __func__); + pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n", + __func__); + } else { + dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc); + } return rc; } EXPORT_SYMBOL_GPL(of_irq_parse_pci); -- cgit v1.2.3 From 261c73f3f6ce0f64ad7da46fd69600f57eec1c11 Mon Sep 17 00:00:00 2001 From: XuYing Date: Sat, 7 Jan 2017 19:04:27 +0800 Subject: of: remove redundant memset in overlay memset in of_build_overlay_info is redundant, the ovinfo has been zeroed in of_fill_overlay_info when error. Signed-off-by: YiPing Xu Signed-off-by: Rob Herring --- drivers/of/overlay.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index d4e337ebcf0f..7827786718d8 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -313,7 +313,6 @@ static int of_build_overlay_info(struct of_overlay *ov, cnt = 0; for_each_child_of_node(tree, node) { - memset(&ovinfo[cnt], 0, sizeof(*ovinfo)); err = of_fill_overlay_info(ov, node, &ovinfo[cnt]); if (err == 0) cnt++; -- cgit v1.2.3 From ca7b89647b76a2f5c26f0927bb72fdaf854d6592 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Thu, 19 Jan 2017 11:06:16 +0100 Subject: of/unittest: Swap arguments of of_unittest_apply_overlay() Function signature of_unittest_apply_overlay(int unittest_nr, int overlay_nr, ... and call sites, like in of_unittest_apply_overlay_check(): ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, ... do not match. Fix this in one place (function signature). The only affected test case is 15, which supplies non-existing overlay number 16, but two bugs matched here. Fix the test case. Signed-off-by: Alexander Sverdlin Cc: Rob Herring Cc: Frank Rowand Cc: devicetree@vger.kernel.org Signed-off-by: Rob Herring --- drivers/of/unittest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index b4e823615f2c..62db55b97c10 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1180,7 +1180,7 @@ static void of_unittest_destroy_tracked_overlays(void) } while (defers > 0); } -static int of_unittest_apply_overlay(int unittest_nr, int overlay_nr, +static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr, int *overlay_id) { struct device_node *np = NULL; @@ -1839,7 +1839,7 @@ static void of_unittest_overlay_i2c_15(void) int ret; /* device should enable */ - ret = of_unittest_apply_overlay_check(16, 15, 0, 1, I2C_OVERLAY); + ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY); if (ret != 0) return; -- cgit v1.2.3 From 0549bde0fcb11a95773e7dc4121738b9e653abf4 Mon Sep 17 00:00:00 2001 From: Qi Hou Date: Mon, 6 Feb 2017 12:55:19 +0800 Subject: of: fix of_node leak caused in of_find_node_opts_by_path During stepping down the tree, parent node is gotten first and its refcount is increased with of_node_get() in __of_get_next_child(). Since it just being used as tmp node, its refcount must be decreased with of_node_put() after traversing its child nodes. Or, its refcount will never be descreased to ZERO, then it will never be freed, as well as other related memory blocks. To fix this, decrease refcount of parent with of_node_put() after __of_find_node_by_path(). Signed-off-by: Qi Hou Acked-by: Peter Rosin Signed-off-by: Rob Herring --- drivers/of/base.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index d4bea3c797d6..ce8206f9f97a 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -842,8 +842,11 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt if (!np) np = of_node_get(of_root); while (np && *path == '/') { + struct device_node *tmp = np; + path++; /* Increment past '/' delimiter */ np = __of_find_node_by_path(np, path); + of_node_put(tmp); path = strchrnul(path, '/'); if (separator && separator < path) break; -- cgit v1.2.3 From e553f539f2af39db5e3b2c273cc1a22d34be49ad Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Mon, 17 Oct 2016 12:17:43 -0700 Subject: of: make of_device_make_bus_id() static of_device_make_bus_id() was changed to non-static by commit c66012253800 ("of/device: Make of_device_make_bus_id() usable by other code") more than 6 years ago, but there are no users of it outside of platform.c. Make the function static again. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/platform.c | 2 +- include/linux/of_device.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index b8064bc2b6eb..5dfcc967dd05 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -76,7 +76,7 @@ EXPORT_SYMBOL(of_find_device_by_node); * derive a unique name. If it cannot, then it will prepend names from * parent nodes until a unique name can be derived. */ -void of_device_make_bus_id(struct device *dev) +static void of_device_make_bus_id(struct device *dev) { struct device_node *node = dev->of_node; const __be32 *reg; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index cc7dd687a89d..5c2aeed17dd4 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -13,7 +13,6 @@ struct device; #ifdef CONFIG_OF extern const struct of_device_id *of_match_device( const struct of_device_id *matches, const struct device *dev); -extern void of_device_make_bus_id(struct device *dev); /** * of_driver_match_device - Tell if a driver's of_match_table matches a device. -- cgit v1.2.3 From bd0096d7467fbfa723cb1c12011098abf16de525 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Mon, 17 Oct 2016 12:21:23 -0700 Subject: of: Add missing space at end of pr_fmt(). Make pr_fmt() in fdt.c consistent with all other files in drivers/of/ Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/fdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c9b5cac03b36..4ae68bc50677 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -9,7 +9,7 @@ * version 2 as published by the Free Software Foundation. */ -#define pr_fmt(fmt) "OF: fdt:" fmt +#define pr_fmt(fmt) "OF: fdt: " fmt #include #include -- cgit v1.2.3 From b85ad494098bf881c3713218fbd74193e5d5c488 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 3 Feb 2017 12:39:03 -0600 Subject: of: introduce of_graph_get_remote_node The OF graph API leaves too much of the graph walking to clients when in many cases the driver doesn't care about accessing the port or endpoint nodes. The drivers typically just want the device connected via a particular graph connection. of_graph_get_remote_node provides this functionality. Signed-off-by: Rob Herring Acked-by: Philipp Zabel --- drivers/of/base.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/of_graph.h | 8 ++++++++ 2 files changed, 45 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index ce8206f9f97a..8f2a1dbfe75c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2472,3 +2472,40 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node) return of_get_next_parent(np); } EXPORT_SYMBOL(of_graph_get_remote_port); + +/** + * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint + * @node: pointer to parent device_node containing graph port/endpoint + * @port: identifier (value of reg property) of the parent port node + * @endpoint: identifier (value of reg property) of the endpoint node + * + * Return: Remote device node associated with remote endpoint node linked + * to @node. Use of_node_put() on it when done. + */ +struct device_node *of_graph_get_remote_node(const struct device_node *node, + u32 port, u32 endpoint) +{ + struct device_node *endpoint_node, *remote; + + endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); + if (!endpoint_node) { + pr_debug("no valid endpoint (%d, %d) for node %s\n", + port, endpoint, node->full_name); + return NULL; + } + + remote = of_graph_get_remote_port_parent(endpoint_node); + of_node_put(endpoint_node); + if (!remote) { + pr_debug("no valid remote node\n"); + return NULL; + } + + if (!of_device_is_available(remote)) { + pr_debug("not available for remote node\n"); + return NULL; + } + + return remote; +} +EXPORT_SYMBOL(of_graph_get_remote_node); diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h index bb3a5a2cd570..abdb02eaef06 100644 --- a/include/linux/of_graph.h +++ b/include/linux/of_graph.h @@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs( struct device_node *of_graph_get_remote_port_parent( const struct device_node *node); struct device_node *of_graph_get_remote_port(const struct device_node *node); +struct device_node *of_graph_get_remote_node(const struct device_node *node, + u32 port, u32 endpoint); #else static inline int of_graph_parse_endpoint(const struct device_node *node, @@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port( { return NULL; } +static inline struct device_node *of_graph_get_remote_node( + const struct device_node *node, + u32 port, u32 endpoint) +{ + return NULL; +} #endif /* CONFIG_OF */ -- cgit v1.2.3