aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/address.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-05 18:57:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-05 18:57:04 -0400
commiteb3d3ec567e868c8a3bfbfdfc9465ffd52983d11 (patch)
tree75acf38b8d73cd281e5ce4dcc941faf48e244b98 /drivers/of/address.c
parentc3c55a07203947f72afa50a3218460b27307c47d (diff)
parentbd63ce27d9d62bc40a962b991cbbbe4f0dc913d2 (diff)
Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into next
Pull ARM updates from Russell King: - Major clean-up of the L2 cache support code. The existing mess was becoming rather unmaintainable through all the additions that others have done over time. This turns it into a much nicer structure, and implements a few performance improvements as well. - Clean up some of the CP15 control register tweaks for alignment support, moving some code and data into alignment.c - DMA properties for ARM, from Santosh and reviewed by DT people. This adds DT properties to specify bus translations we can't discover automatically, and to indicate whether devices are coherent. - Hibernation support for ARM - Make ftrace work with read-only text in modules - add suspend support for PJ4B CPUs - rework interrupt masking for undefined instruction handling, which allows us to enable interrupts earlier in the handling of these exceptions. - support for big endian page tables - fix stacktrace support to exclude stacktrace functions from the trace, and add save_stack_trace_regs() implementation so that kprobes can record stack traces. - Add support for the Cortex-A17 CPU. - Remove last vestiges of ARM710 support. - Removal of ARM "meminfo" structure, finally converting us solely to memblock to handle the early memory initialisation. * 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (142 commits) ARM: ensure C page table setup code follows assembly code (part II) ARM: ensure C page table setup code follows assembly code ARM: consolidate last remaining open-coded alignment trap enable ARM: remove global cr_no_alignment ARM: remove CPU_CP15 conditional from alignment.c ARM: remove unused adjust_cr() function ARM: move "noalign" command line option to alignment.c ARM: provide common method to clear bits in CPU control register ARM: 8025/1: Get rid of meminfo ARM: 8060/1: mm: allow sub-architectures to override PCI I/O memory type ARM: 8066/1: correction for ARM patch 8031/2 ARM: 8049/1: ftrace/add save_stack_trace_regs() implementation ARM: 8065/1: remove last use of CONFIG_CPU_ARM710 ARM: 8062/1: Modify ldrt fixup handler to re-execute the userspace instruction ARM: 8047/1: rwsem: use asm-generic rwsem implementation ARM: l2c: trial at enabling some Cortex-A9 optimisations ARM: l2c: add warnings for stuff modifying aux_ctrl register values ARM: l2c: print a warning with L2C-310 caches if the cache size is modified ARM: l2c: remove old .set_debug method ARM: l2c: kill L2X0_AUX_CTRL_MASK before anyone else makes use of this ...
Diffstat (limited to 'drivers/of/address.c')
-rw-r--r--drivers/of/address.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 95351b2a112c..5edfcb0da37d 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -701,3 +701,113 @@ void __iomem *of_iomap(struct device_node *np, int index)
701 return ioremap(res.start, resource_size(&res)); 701 return ioremap(res.start, resource_size(&res));
702} 702}
703EXPORT_SYMBOL(of_iomap); 703EXPORT_SYMBOL(of_iomap);
704
705/**
706 * of_dma_get_range - Get DMA range info
707 * @np: device node to get DMA range info
708 * @dma_addr: pointer to store initial DMA address of DMA range
709 * @paddr: pointer to store initial CPU address of DMA range
710 * @size: pointer to store size of DMA range
711 *
712 * Look in bottom up direction for the first "dma-ranges" property
713 * and parse it.
714 * dma-ranges format:
715 * DMA addr (dma_addr) : naddr cells
716 * CPU addr (phys_addr_t) : pna cells
717 * size : nsize cells
718 *
719 * It returns -ENODEV if "dma-ranges" property was not found
720 * for this device in DT.
721 */
722int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *size)
723{
724 struct device_node *node = of_node_get(np);
725 const __be32 *ranges = NULL;
726 int len, naddr, nsize, pna;
727 int ret = 0;
728 u64 dmaaddr;
729
730 if (!node)
731 return -EINVAL;
732
733 while (1) {
734 naddr = of_n_addr_cells(node);
735 nsize = of_n_size_cells(node);
736 node = of_get_next_parent(node);
737 if (!node)
738 break;
739
740 ranges = of_get_property(node, "dma-ranges", &len);
741
742 /* Ignore empty ranges, they imply no translation required */
743 if (ranges && len > 0)
744 break;
745
746 /*
747 * At least empty ranges has to be defined for parent node if
748 * DMA is supported
749 */
750 if (!ranges)
751 break;
752 }
753
754 if (!ranges) {
755 pr_debug("%s: no dma-ranges found for node(%s)\n",
756 __func__, np->full_name);
757 ret = -ENODEV;
758 goto out;
759 }
760
761 len /= sizeof(u32);
762
763 pna = of_n_addr_cells(node);
764
765 /* dma-ranges format:
766 * DMA addr : naddr cells
767 * CPU addr : pna cells
768 * size : nsize cells
769 */
770 dmaaddr = of_read_number(ranges, naddr);
771 *paddr = of_translate_dma_address(np, ranges);
772 if (*paddr == OF_BAD_ADDR) {
773 pr_err("%s: translation of DMA address(%pad) to CPU address failed node(%s)\n",
774 __func__, dma_addr, np->full_name);
775 ret = -EINVAL;
776 goto out;
777 }
778 *dma_addr = dmaaddr;
779
780 *size = of_read_number(ranges + naddr + pna, nsize);
781
782 pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
783 *dma_addr, *paddr, *size);
784
785out:
786 of_node_put(node);
787
788 return ret;
789}
790EXPORT_SYMBOL_GPL(of_dma_get_range);
791
792/**
793 * of_dma_is_coherent - Check if device is coherent
794 * @np: device node
795 *
796 * It returns true if "dma-coherent" property was found
797 * for this device in DT.
798 */
799bool of_dma_is_coherent(struct device_node *np)
800{
801 struct device_node *node = of_node_get(np);
802
803 while (node) {
804 if (of_property_read_bool(node, "dma-coherent")) {
805 of_node_put(node);
806 return true;
807 }
808 node = of_get_next_parent(node);
809 }
810 of_node_put(node);
811 return false;
812}
813EXPORT_SYMBOL_GPL(of_dma_is_coherent);