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

of: address: Add support for the parent DMA bus

Some SoCs have devices that are using a separate bus from the main bus to
perform DMA.

These buses might have some restrictions and/or different mapping than from
the CPU side, so we'd need to express those using the usual dma-ranges, but
using a different DT node than the node's parent.

Now that the generic interconnect bindings are available, we can model an
interconnect with the reserved name "dma-mem" for those use-cases.

Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Rob Herring <robh@kernel.org>

authored by

Maxime Ripard and committed by
Rob Herring
f83a6e5d 95835a8d

+26 -2
+26 -2
drivers/of/address.c
··· 677 677 } 678 678 EXPORT_SYMBOL(of_translate_address); 679 679 680 + static struct device_node *__of_get_dma_parent(const struct device_node *np) 681 + { 682 + struct of_phandle_args args; 683 + int ret, index; 684 + 685 + index = of_property_match_string(np, "interconnect-names", "dma-mem"); 686 + if (index < 0) 687 + return of_get_parent(np); 688 + 689 + ret = of_parse_phandle_with_args(np, "interconnects", 690 + "#interconnect-cells", 691 + index, &args); 692 + if (ret < 0) 693 + return of_get_parent(np); 694 + 695 + return of_node_get(args.np); 696 + } 697 + 680 698 u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) 681 699 { 682 700 struct device_node *host; 683 701 u64 ret; 684 702 685 - ret = __of_translate_address(dev, of_get_parent, 703 + ret = __of_translate_address(dev, __of_get_dma_parent, 686 704 in_addr, "dma-ranges", &host); 687 705 688 706 if (host) { ··· 930 912 return -EINVAL; 931 913 932 914 while (1) { 915 + struct device_node *parent; 916 + 933 917 naddr = of_n_addr_cells(node); 934 918 nsize = of_n_size_cells(node); 935 - node = of_get_next_parent(node); 919 + 920 + parent = __of_get_dma_parent(node); 921 + of_node_put(node); 922 + 923 + node = parent; 936 924 if (!node) 937 925 break; 938 926