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

dma: coh901318: add devicetree support

This adds support for probing the COH 901 318 DMA controller
and channels from the device tree.

Contains portions of a sketch patch from Arnd Bergmann.

Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+75
+32
Documentation/devicetree/bindings/dma/ste-coh901318.txt
··· 1 + ST-Ericsson COH 901 318 DMA Controller 2 + 3 + This is a DMA controller which has begun as a fork of the 4 + ARM PL08x PrimeCell VHDL code. 5 + 6 + Required properties: 7 + - compatible: should be "stericsson,coh901318" 8 + - reg: register locations and length 9 + - interrupts: the single DMA IRQ 10 + - #dma-cells: must be set to <1>, as the channels on the 11 + COH 901 318 are simple and identified by a single number 12 + - dma-channels: the number of DMA channels handled 13 + 14 + Example: 15 + 16 + dmac: dma-controller@c00020000 { 17 + compatible = "stericsson,coh901318"; 18 + reg = <0xc0020000 0x1000>; 19 + interrupt-parent = <&vica>; 20 + interrupts = <2>; 21 + #dma-cells = <1>; 22 + dma-channels = <40>; 23 + }; 24 + 25 + Consumers example: 26 + 27 + uart0: serial@c0013000 { 28 + compatible = "..."; 29 + (...) 30 + dmas = <&dmac 17 &dmac 18>; 31 + dma-names = "tx", "rx"; 32 + };
+43
drivers/dma/coh901318.c
··· 22 22 #include <linux/uaccess.h> 23 23 #include <linux/debugfs.h> 24 24 #include <linux/platform_data/dma-coh901318.h> 25 + #include <linux/of_dma.h> 25 26 26 27 #include "coh901318.h" 27 28 #include "dmaengine.h" ··· 1789 1788 } 1790 1789 EXPORT_SYMBOL(coh901318_filter_id); 1791 1790 1791 + struct coh901318_filter_args { 1792 + struct coh901318_base *base; 1793 + unsigned int ch_nr; 1794 + }; 1795 + 1796 + static bool coh901318_filter_base_and_id(struct dma_chan *chan, void *data) 1797 + { 1798 + struct coh901318_filter_args *args = data; 1799 + 1800 + if (&args->base->dma_slave == chan->device && 1801 + args->ch_nr == to_coh901318_chan(chan)->id) 1802 + return true; 1803 + 1804 + return false; 1805 + } 1806 + 1807 + static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec, 1808 + struct of_dma *ofdma) 1809 + { 1810 + struct coh901318_filter_args args = { 1811 + .base = ofdma->of_dma_data, 1812 + .ch_nr = dma_spec->args[0], 1813 + }; 1814 + dma_cap_mask_t cap; 1815 + dma_cap_zero(cap); 1816 + dma_cap_set(DMA_SLAVE, cap); 1817 + 1818 + return dma_request_channel(cap, coh901318_filter_base_and_id, &args); 1819 + } 1792 1820 /* 1793 1821 * DMA channel allocation 1794 1822 */ ··· 2765 2735 if (err) 2766 2736 goto err_register_memcpy; 2767 2737 2738 + err = of_dma_controller_register(pdev->dev.of_node, coh901318_xlate, 2739 + base); 2740 + if (err) 2741 + goto err_register_of_dma; 2742 + 2768 2743 platform_set_drvdata(pdev, base); 2769 2744 dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n", 2770 2745 (u32) base->virtbase); 2771 2746 2772 2747 return err; 2773 2748 2749 + err_register_of_dma: 2750 + dma_async_device_unregister(&base->dma_memcpy); 2774 2751 err_register_memcpy: 2775 2752 dma_async_device_unregister(&base->dma_slave); 2776 2753 err_register_slave: ··· 2789 2752 { 2790 2753 struct coh901318_base *base = platform_get_drvdata(pdev); 2791 2754 2755 + of_dma_controller_free(pdev->dev.of_node); 2792 2756 dma_async_device_unregister(&base->dma_memcpy); 2793 2757 dma_async_device_unregister(&base->dma_slave); 2794 2758 coh901318_pool_destroy(&base->pool); 2795 2759 return 0; 2796 2760 } 2797 2761 2762 + static const struct of_device_id coh901318_dt_match[] = { 2763 + { .compatible = "stericsson,coh901318" }, 2764 + {}, 2765 + }; 2798 2766 2799 2767 static struct platform_driver coh901318_driver = { 2800 2768 .remove = coh901318_remove, 2801 2769 .driver = { 2802 2770 .name = "coh901318", 2771 + .of_match_table = coh901318_dt_match, 2803 2772 }, 2804 2773 }; 2805 2774