forked from mirrors/linux
		
	dmaengine: sirf: enable generic dt binding for dma channels
move to support of_dma_request_slave_channel() and dma_request_slave_channel. we add a xlate() to let dma clients be able to find right dma_chan by generic "dmas" properties in dts. Cc: Mark Rutland <mark.rutland@arm.com> Cc: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Barry Song <Baohua.Song@csr.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
		
							parent
							
								
									80b0e0abfb
								
							
						
					
					
						commit
						2e041c9462
					
				
					 4 changed files with 70 additions and 0 deletions
				
			
		
							
								
								
									
										43
									
								
								Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,43 @@
 | 
				
			||||||
 | 
					* CSR SiRFSoC DMA controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See dma.txt first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					- compatible: Should be "sirf,prima2-dmac" or "sirf,marco-dmac"
 | 
				
			||||||
 | 
					- reg: Should contain DMA registers location and length.
 | 
				
			||||||
 | 
					- interrupts: Should contain one interrupt shared by all channel
 | 
				
			||||||
 | 
					- #dma-cells: must be <1>. used to represent the number of integer
 | 
				
			||||||
 | 
					    cells in the dmas property of client device.
 | 
				
			||||||
 | 
					- clocks: clock required
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Controller:
 | 
				
			||||||
 | 
					dmac0: dma-controller@b00b0000 {
 | 
				
			||||||
 | 
						compatible = "sirf,prima2-dmac";
 | 
				
			||||||
 | 
						reg = <0xb00b0000 0x10000>;
 | 
				
			||||||
 | 
						interrupts = <12>;
 | 
				
			||||||
 | 
						clocks = <&clks 24>;
 | 
				
			||||||
 | 
						#dma-cells = <1>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Client:
 | 
				
			||||||
 | 
					Fill the specific dma request line in dmas. In the below example, spi0 read
 | 
				
			||||||
 | 
					channel request line is 9 of the 2nd dma controller, while write channel uses
 | 
				
			||||||
 | 
					4 of the 2nd dma controller; spi1 read channel request line is 12 of the 1st
 | 
				
			||||||
 | 
					dma controller, while write channel uses 13 of the 1st dma controller:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spi0: spi@b00d0000 {
 | 
				
			||||||
 | 
						compatible = "sirf,prima2-spi";
 | 
				
			||||||
 | 
						dmas = <&dmac1 9>,
 | 
				
			||||||
 | 
							<&dmac1 4>;
 | 
				
			||||||
 | 
						dma-names = "rx", "tx";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					spi1: spi@b0170000 {
 | 
				
			||||||
 | 
						compatible = "sirf,prima2-spi";
 | 
				
			||||||
 | 
						dmas = <&dmac0 12>,
 | 
				
			||||||
 | 
							<&dmac0 13>;
 | 
				
			||||||
 | 
						dma-names = "rx", "tx";
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -269,6 +269,7 @@ dmac0: dma-controller@b00b0000 {
 | 
				
			||||||
				reg = <0xb00b0000 0x10000>;
 | 
									reg = <0xb00b0000 0x10000>;
 | 
				
			||||||
				interrupts = <12>;
 | 
									interrupts = <12>;
 | 
				
			||||||
				clocks = <&clks 24>;
 | 
									clocks = <&clks 24>;
 | 
				
			||||||
 | 
									#dma-cells = <1>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dmac1: dma-controller@b0160000 {
 | 
								dmac1: dma-controller@b0160000 {
 | 
				
			||||||
| 
						 | 
					@ -277,6 +278,7 @@ dmac1: dma-controller@b0160000 {
 | 
				
			||||||
				reg = <0xb0160000 0x10000>;
 | 
									reg = <0xb0160000 0x10000>;
 | 
				
			||||||
				interrupts = <13>;
 | 
									interrupts = <13>;
 | 
				
			||||||
				clocks = <&clks 25>;
 | 
									clocks = <&clks 25>;
 | 
				
			||||||
 | 
									#dma-cells = <1>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			vip@b00C0000 {
 | 
								vip@b00C0000 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,6 +286,7 @@ dmac0: dma-controller@b00b0000 {
 | 
				
			||||||
				reg = <0xb00b0000 0x10000>;
 | 
									reg = <0xb00b0000 0x10000>;
 | 
				
			||||||
				interrupts = <12>;
 | 
									interrupts = <12>;
 | 
				
			||||||
				clocks = <&clks 24>;
 | 
									clocks = <&clks 24>;
 | 
				
			||||||
 | 
									#dma-cells = <1>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dmac1: dma-controller@b0160000 {
 | 
								dmac1: dma-controller@b0160000 {
 | 
				
			||||||
| 
						 | 
					@ -294,6 +295,7 @@ dmac1: dma-controller@b0160000 {
 | 
				
			||||||
				reg = <0xb0160000 0x10000>;
 | 
									reg = <0xb0160000 0x10000>;
 | 
				
			||||||
				interrupts = <13>;
 | 
									interrupts = <13>;
 | 
				
			||||||
				clocks = <&clks 25>;
 | 
									clocks = <&clks 25>;
 | 
				
			||||||
 | 
									#dma-cells = <1>;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			vip@b00C0000 {
 | 
								vip@b00C0000 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
#include <linux/of_device.h>
 | 
					#include <linux/of_device.h>
 | 
				
			||||||
#include <linux/of_platform.h>
 | 
					#include <linux/of_platform.h>
 | 
				
			||||||
#include <linux/clk.h>
 | 
					#include <linux/clk.h>
 | 
				
			||||||
 | 
					#include <linux/of_dma.h>
 | 
				
			||||||
#include <linux/sirfsoc_dma.h>
 | 
					#include <linux/sirfsoc_dma.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dmaengine.h"
 | 
					#include "dmaengine.h"
 | 
				
			||||||
| 
						 | 
					@ -659,6 +660,18 @@ static int sirfsoc_dma_device_slave_caps(struct dma_chan *dchan,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
 | 
				
			||||||
 | 
						struct of_dma *ofdma)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sirfsoc_dma *sdma = ofdma->of_dma_data;
 | 
				
			||||||
 | 
						unsigned int request = dma_spec->args[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (request > SIRFSOC_DMA_CHANNELS)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dma_get_slave_channel(&sdma->channels[request].chan);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sirfsoc_dma_probe(struct platform_device *op)
 | 
					static int sirfsoc_dma_probe(struct platform_device *op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct device_node *dn = op->dev.of_node;
 | 
						struct device_node *dn = op->dev.of_node;
 | 
				
			||||||
| 
						 | 
					@ -764,11 +777,20 @@ static int sirfsoc_dma_probe(struct platform_device *op)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto free_irq;
 | 
							goto free_irq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Device-tree DMA controller registration */
 | 
				
			||||||
 | 
						ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma);
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
							dev_err(dev, "failed to register DMA controller\n");
 | 
				
			||||||
 | 
							goto unreg_dma_dev;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_enable(&op->dev);
 | 
						pm_runtime_enable(&op->dev);
 | 
				
			||||||
	dev_info(dev, "initialized SIRFSOC DMAC driver\n");
 | 
						dev_info(dev, "initialized SIRFSOC DMAC driver\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unreg_dma_dev:
 | 
				
			||||||
 | 
						dma_async_device_unregister(dma);
 | 
				
			||||||
free_irq:
 | 
					free_irq:
 | 
				
			||||||
	free_irq(sdma->irq, sdma);
 | 
						free_irq(sdma->irq, sdma);
 | 
				
			||||||
irq_dispose:
 | 
					irq_dispose:
 | 
				
			||||||
| 
						 | 
					@ -781,6 +803,7 @@ static int sirfsoc_dma_remove(struct platform_device *op)
 | 
				
			||||||
	struct device *dev = &op->dev;
 | 
						struct device *dev = &op->dev;
 | 
				
			||||||
	struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
 | 
						struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						of_dma_controller_free(op->dev.of_node);
 | 
				
			||||||
	dma_async_device_unregister(&sdma->dma);
 | 
						dma_async_device_unregister(&sdma->dma);
 | 
				
			||||||
	free_irq(sdma->irq, sdma);
 | 
						free_irq(sdma->irq, sdma);
 | 
				
			||||||
	irq_dispose_mapping(sdma->irq);
 | 
						irq_dispose_mapping(sdma->irq);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue