diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 21:55:37 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-07 21:55:37 -0700 |
commit | 82efe439599439a5e1e225ce5740e6cfb777a7dd (patch) | |
tree | ef8b08a66b2c1f538519fd40a7538ca8aa6e12ef /drivers/of/address.c | |
parent | Merge tag 'random_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random (diff) | |
parent | of: unittest: Remove error printing on OOM (diff) | |
download | linux-dev-82efe439599439a5e1e225ce5740e6cfb777a7dd.tar.xz linux-dev-82efe439599439a5e1e225ce5740e6cfb777a7dd.zip |
Merge tag 'devicetree-for-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull Devicetree updates from Rob Herring:
- Fix possible memory leak in reserved-memory failure case
- Support for DMA parent bus which are not a parent node
- Clang -Wunsequenced fix
- Remove some unnecessary prints on memory alloc failures
- Various printk msg and comment fixes
- Update DT schema tools repository location
- Convert simple-framebuffer binding to DT schema
- Bindings for isl68137 and ir38064 trivial devices
- New documentation on binding do's and don't's for binding writers to
ignore
* tag 'devicetree-for-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (22 commits)
of: unittest: Remove error printing on OOM
of: irq: Remove WARN_ON() for kzalloc() failure
dt-bindings: pinctrl: fix bias-pull,up typo
dt-bindings: Update schema project location to devicetree.org github group
of: fix clang -Wunsequenced for be32_to_cpu()
of/device.c: fix the wrong comments
dt-bindings: Add isl68137 as a trivial device
dt-bindings: Add ir38064 as a trivial device
of: del redundant type conversion
dt-bindings: mfd: axp20x: Add fallback for axp805
of: Improve of_phandle_iterator_next() error message
dt-bindings: connector: Spelling mistake
dt-bindings: Add schemas for simple-framebuffer
of: address: Add support for the parent DMA bus
of: address: Retrieve a parent through a callback in __of_translate_address
dt-bindings: bus: Add binding for the Allwinner MBUS controller
dt-bindings: interconnect: Add a dma interconnect name
of: use correct function prototype for of_overlay_fdt_apply()
of: reserved_mem: fix reserve memory leak
of: property: Document that of_graph_get_endpoint_by_regs needs of_node_put
...
Diffstat (limited to 'drivers/of/address.c')
-rw-r--r-- | drivers/of/address.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index 2270373b30ab..978427a9d5e6 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -569,6 +569,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * relative to that node. */ static u64 __of_translate_address(struct device_node *dev, + struct device_node *(*get_parent)(const struct device_node *), const __be32 *in_addr, const char *rprop, struct device_node **host) { @@ -585,7 +586,7 @@ static u64 __of_translate_address(struct device_node *dev, *host = NULL; /* Get parent & match bus type */ - parent = of_get_parent(dev); + parent = get_parent(dev); if (parent == NULL) goto bail; bus = of_match_bus(parent); @@ -609,7 +610,7 @@ static u64 __of_translate_address(struct device_node *dev, /* Switch to parent bus */ of_node_put(dev); dev = parent; - parent = of_get_parent(dev); + parent = get_parent(dev); /* If root, we have finished */ if (parent == NULL) { @@ -665,7 +666,8 @@ u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) struct device_node *host; u64 ret; - ret = __of_translate_address(dev, in_addr, "ranges", &host); + ret = __of_translate_address(dev, of_get_parent, + in_addr, "ranges", &host); if (host) { of_node_put(host); return OF_BAD_ADDR; @@ -675,12 +677,31 @@ u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) } EXPORT_SYMBOL(of_translate_address); +static struct device_node *__of_get_dma_parent(const struct device_node *np) +{ + struct of_phandle_args args; + int ret, index; + + index = of_property_match_string(np, "interconnect-names", "dma-mem"); + if (index < 0) + return of_get_parent(np); + + ret = of_parse_phandle_with_args(np, "interconnects", + "#interconnect-cells", + index, &args); + if (ret < 0) + return of_get_parent(np); + + return of_node_get(args.np); +} + u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) { struct device_node *host; u64 ret; - ret = __of_translate_address(dev, in_addr, "dma-ranges", &host); + ret = __of_translate_address(dev, __of_get_dma_parent, + in_addr, "dma-ranges", &host); if (host) { of_node_put(host); @@ -736,7 +757,8 @@ static u64 of_translate_ioport(struct device_node *dev, const __be32 *in_addr, unsigned long port; struct device_node *host; - taddr = __of_translate_address(dev, in_addr, "ranges", &host); + taddr = __of_translate_address(dev, of_get_parent, + in_addr, "ranges", &host); if (host) { /* host-specific port access */ port = logic_pio_trans_hwaddr(&host->fwnode, taddr, size); @@ -908,9 +930,15 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz return -EINVAL; while (1) { + struct device_node *parent; + naddr = of_n_addr_cells(node); nsize = of_n_size_cells(node); - node = of_get_next_parent(node); + + parent = __of_get_dma_parent(node); + of_node_put(node); + + node = parent; if (!node) break; |